@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
112 lines (111 loc) • 3.41 kB
JavaScript
"use strict";
import { UniformName } from "./UniformsController";
import { LightType, getLightType } from "./raymarching/_Base";
import {
_resetSpotLightIndex,
_updateUniformsWithSpotLight
} from "./raymarching/SpotLight";
import {
_resetDirectionalLightIndex,
_updateUniformsWithDirectionalLight
} from "./raymarching/DirectionalLight";
import {
_resetPointLightIndex,
_updateUniformsWithPointLight
} from "./raymarching/PointLight";
function _updateUniformsFunctionForLight(object) {
const lightType = getLightType(object);
switch (lightType) {
case LightType.SPOT: {
return _updateUniformsWithSpotLight;
}
case LightType.DIRECTIONAL: {
return _updateUniformsWithDirectionalLight;
}
case LightType.POINT: {
return _updateUniformsWithPointLight;
}
}
}
export class SceneTraverserController {
constructor(scene) {
this.scene = scene;
this._spotLightsRayMarching = {
value: []
};
this._directionalLightsRayMarching = {
value: []
};
// private _hemisphereLightsRayMarching: HemisphereLightRayMarchingUniform = {
// value: [],
// };
this._pointLightsRayMarching = {
value: []
};
// private _areaLightsRayMarching: AreaLightRayMarchingUniform = {
// value: [],
// // properties: {
// // worldPos: {},
// // },
// };
this._updateUniformsFunctionByLight = /* @__PURE__ */ new WeakMap();
this._uniformsByLight = /* @__PURE__ */ new WeakMap();
this._onObjectTraverseBound = this._onObjectTraverse.bind(this);
}
traverseScene(scene) {
_resetSpotLightIndex();
_resetDirectionalLightIndex();
_resetPointLightIndex();
scene = scene || this.scene.threejsScene();
scene.traverse(this._onObjectTraverseBound);
}
_onObjectTraverse(object) {
let updateFunction = this._updateUniformsFunctionByLight.get(object);
if (!updateFunction) {
if (object.isLight) {
updateFunction = _updateUniformsFunctionForLight(object);
if (updateFunction) {
this._updateUniformsFunctionByLight.set(object, updateFunction);
}
}
}
if (!updateFunction) {
return updateFunction;
}
let uniforms = this._uniformsByLight.get(object);
if (!uniforms) {
uniforms = this._updateUniformsForLight(object);
if (uniforms) {
this._uniformsByLight.set(object, uniforms);
}
}
if (!uniforms) {
return;
}
updateFunction(object, uniforms);
}
_updateUniformsForLight(object) {
const lightType = getLightType(object);
switch (lightType) {
case LightType.SPOT: {
return this._spotLightsRayMarching;
}
case LightType.DIRECTIONAL: {
return this._directionalLightsRayMarching;
}
case LightType.POINT: {
return this._pointLightsRayMarching;
}
}
}
addLightsRayMarchingUniform(uniforms) {
uniforms[UniformName.SPOTLIGHTS_RAYMARCHING] = this._spotLightsRayMarching;
uniforms[UniformName.DIRECTIONALLIGHTS_RAYMARCHING] = this._directionalLightsRayMarching;
uniforms[UniformName.POINTLIGHTS_RAYMARCHING] = this._pointLightsRayMarching;
}
removeLightsRayMarchingUniform(uniforms) {
delete uniforms[UniformName.SPOTLIGHTS_RAYMARCHING];
delete uniforms[UniformName.DIRECTIONALLIGHTS_RAYMARCHING];
delete uniforms[UniformName.POINTLIGHTS_RAYMARCHING];
}
}