UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

148 lines (143 loc) 4.94 kB
import {UniformName} from './UniformsController'; import {PolyScene} from '../PolyScene'; import {IUniforms} from '../../../core/geometry/Material'; import { Scene, Object3D, Light, IUniform, // RectAreaLight, } from 'three'; import {LightType, getLightType, AvailableLight, UniformsUpdateFunction} from './raymarching/_Base'; import { _resetSpotLightIndex, _updateUniformsWithSpotLight, SpotLightRayMarchingUniform, _createSpotLightUniform, } from './raymarching/SpotLight'; import { _resetDirectionalLightIndex, _updateUniformsWithDirectionalLight, DirectionalLightRayMarchingUniform, _createDirectionalLightUniform, } from './raymarching/DirectionalLight'; // import { // _resetHemisphereLightIndex, // _updateUniformsWithHemisphereLight, // HemisphereLightRayMarchingUniform, // _createHemisphereLightUniform, // } from './raymarching/HemisphereLight'; import { _resetPointLightIndex, _updateUniformsWithPointLight, PointLightRayMarchingUniform, _createPointLightUniform, } from './raymarching/PointLight'; function _updateUniformsFunctionForLight<L extends AvailableLight>( object: L ): UniformsUpdateFunction<AvailableLight> | undefined { const lightType = getLightType(object as Light); switch (lightType) { case LightType.SPOT: { return _updateUniformsWithSpotLight as UniformsUpdateFunction<AvailableLight>; } case LightType.DIRECTIONAL: { return _updateUniformsWithDirectionalLight as UniformsUpdateFunction<AvailableLight>; } // case LightType.HEMISPHERE: { // return _updateUniformsWithHemisphereLight as UniformsUpdateFunction<AvailableLight>; // } case LightType.POINT: { return _updateUniformsWithPointLight as UniformsUpdateFunction<AvailableLight>; } } } export class SceneTraverserController { private _spotLightsRayMarching: SpotLightRayMarchingUniform = { value: [], }; private _directionalLightsRayMarching: DirectionalLightRayMarchingUniform = { value: [], }; // private _hemisphereLightsRayMarching: HemisphereLightRayMarchingUniform = { // value: [], // }; private _pointLightsRayMarching: PointLightRayMarchingUniform = { value: [], }; // private _areaLightsRayMarching: AreaLightRayMarchingUniform = { // value: [], // // properties: { // // worldPos: {}, // // }, // }; private _updateUniformsFunctionByLight: WeakMap<AvailableLight, UniformsUpdateFunction<AvailableLight>> = new WeakMap(); private _uniformsByLight: WeakMap<Light, IUniform> = new WeakMap(); constructor(protected scene: PolyScene) {} traverseScene(scene?: Scene) { _resetSpotLightIndex(); _resetDirectionalLightIndex(); // _resetHemisphereLightIndex(); _resetPointLightIndex(); scene = scene || this.scene.threejsScene(); scene.traverse(this._onObjectTraverseBound); } private _onObjectTraverseBound = this._onObjectTraverse.bind(this); private _onObjectTraverse(object: Object3D) { let updateFunction = this._updateUniformsFunctionByLight.get(object as AvailableLight); if (!updateFunction) { if ((object as Light).isLight) { updateFunction = _updateUniformsFunctionForLight(object as AvailableLight); if (updateFunction) { this._updateUniformsFunctionByLight.set(object as AvailableLight, updateFunction); } } } if (!updateFunction) { return updateFunction; } let uniforms = this._uniformsByLight.get(object as Light); if (!uniforms) { uniforms = this._updateUniformsForLight(object as Light); if (uniforms) { this._uniformsByLight.set(object as Light, uniforms); } } if (!uniforms) { return; } updateFunction(object as AvailableLight, uniforms); } private _updateUniformsForLight<L extends Light>(object: L) { const lightType = getLightType(object as Light); switch (lightType) { case LightType.SPOT: { return this._spotLightsRayMarching; } case LightType.DIRECTIONAL: { return this._directionalLightsRayMarching; } // case LightType.HEMISPHERE: { // return this._hemisphereLightsRayMarching; // } case LightType.POINT: { return this._pointLightsRayMarching; } } } addLightsRayMarchingUniform(uniforms: IUniforms) { uniforms[UniformName.SPOTLIGHTS_RAYMARCHING] = this._spotLightsRayMarching; uniforms[UniformName.DIRECTIONALLIGHTS_RAYMARCHING] = this._directionalLightsRayMarching; // uniforms[UniformName.HEMISPHERELIGHTS_RAYMARCHING] = this._hemisphereLightsRayMarching; uniforms[UniformName.POINTLIGHTS_RAYMARCHING] = this._pointLightsRayMarching; // uniforms[UniformName.AREALIGHTS_RAYMARCHING] = this._areaLightsRayMarching; } removeLightsRayMarchingUniform(uniforms: IUniforms) { delete uniforms[UniformName.SPOTLIGHTS_RAYMARCHING]; delete uniforms[UniformName.DIRECTIONALLIGHTS_RAYMARCHING]; // delete uniforms[UniformName.HEMISPHERELIGHTS_RAYMARCHING]; delete uniforms[UniformName.POINTLIGHTS_RAYMARCHING]; // uniforms[UniformName.AREALIGHTS_RAYMARCHING] = this._areaLightsRayMarching; } }