diff --git a/src/materials/nodes/NodeMaterial.js b/src/materials/nodes/NodeMaterial.js index aba3037755cea5..c498b866c498c5 100644 --- a/src/materials/nodes/NodeMaterial.js +++ b/src/materials/nodes/NodeMaterial.js @@ -994,14 +994,6 @@ class NodeMaterial extends Material { const materialLightsNode = []; - if ( builder.renderer.lighting.enabled === false ) { - - return materialLightsNode; - - } - - // - const envNode = this.setupEnvironment( builder ); if ( envNode && envNode.isLightingNode ) { @@ -1087,9 +1079,10 @@ class NodeMaterial extends Material { // OUTGOING LIGHT - const lights = this.lights === true || this.lightsNode !== null; + const sceneLighting = this.lights === true && builder.renderer.lighting.enabled; + const lights = sceneLighting || this.lightsNode !== null; - const materialLightings = this.lights === true ? this.setupMaterialLightings( builder ) : []; + const materialLightings = sceneLighting ? this.setupMaterialLightings( builder ) : []; const lightsNode = lights ? ( this.lightsNode || builder.lightsNode ) : null; let outgoingLightNode = this.setupOutgoingLight( builder ); diff --git a/src/nodes/display/PassNode.js b/src/nodes/display/PassNode.js index 48bddcc4b8ae04..69268c142dfcb4 100644 --- a/src/nodes/display/PassNode.js +++ b/src/nodes/display/PassNode.js @@ -289,6 +289,8 @@ class PassNode extends TempNode { */ this.opaque = true; + this.lighting = null; + /** * Whether the renderer should automatically clear before rendering the pass. * @@ -844,6 +846,7 @@ class PassNode extends TempNode { const currentAutoClearStencil = renderer.autoClearStencil; const currentTransparent = renderer.transparent; const currentOpaque = renderer.opaque; + const currentLighting = renderer.lighting; const currentMask = camera.layers.mask; const currentContextNode = renderer.contextNode; const currentOverrideMaterial = scene.overrideMaterial; @@ -878,6 +881,12 @@ class PassNode extends TempNode { renderer.transparent = this.transparent; renderer.opaque = this.opaque; + if ( this.lighting !== null ) { + + renderer.lighting = this.lighting; + + } + if ( this.contextNode !== null ) { if ( this._contextNodeCache === null || this._contextNodeCache.version !== this.version ) { @@ -911,6 +920,7 @@ class PassNode extends TempNode { renderer.transparent = currentTransparent; renderer.opaque = currentOpaque; renderer.contextNode = currentContextNode; + renderer.lighting = currentLighting; camera.layers.mask = currentMask; diff --git a/src/renderers/common/Lighting.js b/src/renderers/common/Lighting.js index 94c5e259ce30be..75597b53917c39 100644 --- a/src/renderers/common/Lighting.js +++ b/src/renderers/common/Lighting.js @@ -1,11 +1,10 @@ import { LightsNode } from '../../nodes/Nodes.js'; const _defaultLights = /*@__PURE__*/ new LightsNode(); -const _weakMap = /*@__PURE__*/ new WeakMap(); /** * This renderer module manages the lights nodes which are unique - * per scene and camera combination. + * per scene + camera + lighting combination. * * The lights node itself is later configured in the render list * with the actual lights from the scene. @@ -35,6 +34,14 @@ class Lighting { */ this._cache = []; + /** + * A map of lights nodes per scene. + * + * @private + * @type {WeakMap} + */ + this._lightsNodeMap = new WeakMap(); + } /** @@ -60,12 +67,12 @@ class Lighting { // Ignore renderable objects, e.g: Mesh, Sprite, etc. if ( scene.isScene !== true && scene.isGroup !== true ) return _defaultLights; - let node = _weakMap.get( scene ); + let node = this._lightsNodeMap.get( scene ); if ( node === undefined ) { node = this.createNode(); - _weakMap.set( scene, node ); + this._lightsNodeMap.set( scene, node ); } diff --git a/src/renderers/common/RenderLists.js b/src/renderers/common/RenderLists.js index a9d4962def8159..618449fb161e39 100644 --- a/src/renderers/common/RenderLists.js +++ b/src/renderers/common/RenderLists.js @@ -13,17 +13,8 @@ class RenderLists { /** * Constructs a render lists management component. - * - * @param {Lighting} lighting - The lighting management component. */ - constructor( lighting ) { - - /** - * The lighting management component. - * - * @type {Lighting} - */ - this.lighting = lighting; + constructor() { /** * The internal chain map which holds the render lists. @@ -56,26 +47,29 @@ class RenderLists { * * @param {Scene} scene - The scene. * @param {Camera} camera - The camera. + * @param {Lighting} lighting - The lighting manager. * @return {RenderList} The render list. */ - get( scene, camera ) { + get( scene, camera, lighting ) { const lists = this.lists; _chainKeys[ 0 ] = scene; _chainKeys[ 1 ] = camera; + _chainKeys[ 2 ] = lighting; let list = lists.get( _chainKeys ); if ( list === undefined ) { - list = new RenderList( this.lighting, scene, camera ); + list = new RenderList( lighting, scene, camera ); lists.set( _chainKeys, list ); } _chainKeys[ 0 ] = null; _chainKeys[ 1 ] = null; + _chainKeys[ 2 ] = null; // diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 81ed62fc839f5d..a6dfd09ba69929 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -757,7 +757,7 @@ class Renderer { const useFrameBufferTarget = this.needsFrameBufferTarget && this._renderTarget === null; const renderTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : ( this._renderTarget || this._outputRenderTarget ); - const renderList = this._renderLists.get( scene, camera ); + const renderList = this._renderLists.get( scene, camera, this.lighting ); const renderContext = this._renderContexts.get( renderTarget, this._mrt ); const material = scene.overrideMaterial || object.material; @@ -831,7 +831,7 @@ class Renderer { this._pipelines = new Pipelines( backend, this._nodes, this.info ); this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info ); this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info ); - this._renderLists = new RenderLists( this.lighting ); + this._renderLists = new RenderLists(); this._bundles = new RenderBundles(); this._renderContexts = new RenderContexts( this ); @@ -982,7 +982,7 @@ class Renderer { } // Use sceneRef for render list to ensure lightsNode matches between compileAsync and render - const renderList = this._renderLists.get( sceneRef, camera ); + const renderList = this._renderLists.get( sceneRef, camera, this.lighting ); renderList.begin(); this._projectObject( scene, camera, 0, renderList, renderContext.clippingContext ); @@ -1708,7 +1708,7 @@ class Renderer { this._renderLists.update( nodeFrame.frameId ); - const renderList = this._renderLists.get( scene, camera ); + const renderList = this._renderLists.get( scene, camera, this.lighting ); renderList.begin(); this._projectObject( scene, camera, 0, renderList, renderContext.clippingContext ); @@ -3235,7 +3235,7 @@ class Renderer { // replace render list - renderList = this._renderLists.get( object, camera ); + renderList = this._renderLists.get( object, camera, this.lighting ); const renderBundle = this._bundles.get( object, camera, this._currentRenderContext ); const renderBundleData = this.backend.get( renderBundle );