Просмотр исходного кода

Renderer: Fix light invalidation by nested render calls. (#33737)

Michael Herzog 1 неделя назад
Родитель
Сommit
618d8ed3eb
2 измененных файлов с 40 добавлено и 2 удалено
  1. 36 2
      src/renderers/common/Lighting.js
  2. 4 0
      src/renderers/common/Renderer.js

+ 36 - 2
src/renderers/common/Lighting.js

@@ -27,6 +27,14 @@ class Lighting {
 		 */
 		this.enabled = true;
 
+		/**
+		 * A stack of light arrays saved per render via {@link Lighting#beginRender}.
+		 *
+		 * @private
+		 * @type {Array<Array<Light>>}
+		 */
+		this._cache = [];
+
 	}
 
 	/**
@@ -42,10 +50,9 @@ class Lighting {
 	}
 
 	/**
-	 * Returns a lights node for the given scene and camera.
+	 * Returns a lights node for the given scene.
 	 *
 	 * @param {Scene} scene - The scene.
-	 * @param {Camera} camera - The camera.
 	 * @return {LightsNode} The lights node.
 	 */
 	getNode( scene ) {
@@ -66,6 +73,33 @@ class Lighting {
 
 	}
 
+	/**
+	 * Saves the current lights of the scene's lights node so they can be restored
+	 * in {@link Lighting#finishRender}. Must be paired with a `finishRender()` call
+	 * to avoid memory leaks.
+	 *
+	 * Nested render calls might mutate the lights array so a save/restore is required
+	 * for each render call.
+	 *
+	 * @param {Scene} scene - The scene.
+	 */
+	beginRender( scene ) {
+
+		this._cache.push( this.getNode( scene ).getLights() );
+
+	}
+
+	/**
+	 * Restores the lights saved by the matching {@link Lighting#beginRender} call.
+	 *
+	 * @param {Scene} scene - The scene.
+	 */
+	finishRender( scene ) {
+
+		this.getNode( scene ).setLights( this._cache.pop() );
+
+	}
+
 }
 
 export default Lighting;

+ 4 - 0
src/renderers/common/Renderer.js

@@ -1522,6 +1522,8 @@ class Renderer {
 		const previousRenderObjectFunction = this._currentRenderObjectFunction;
 		const previousHandleObjectFunction = this._handleObjectFunction;
 
+		this.lighting.beginRender( scene );
+
 		//
 
 		this._callDepth ++;
@@ -1748,6 +1750,8 @@ class Renderer {
 		this._currentRenderObjectFunction = previousRenderObjectFunction;
 		this._handleObjectFunction = previousHandleObjectFunction;
 
+		this.lighting.finishRender( scene );
+
 		//
 
 		this._callDepth --;

粤ICP备19079148号