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

RenderContext: Refactor context key. (#32546)

Michael Herzog 4 месяцев назад
Родитель
Сommit
20d7ef8a8e

+ 8 - 0
src/renderers/common/RenderContext.js

@@ -214,6 +214,14 @@ class RenderContext {
 		 */
 		this.clippingContext = null;
 
+		/**
+		 * The current camera.
+		 *
+		 * @type {?Camera}
+		 * @default null
+		 */
+		this.camera = null;
+
 		/**
 		 * This flag can be used for type testing.
 		 *

+ 19 - 55
src/renderers/common/RenderContexts.js

@@ -1,11 +1,4 @@
-import ChainMap from './ChainMap.js';
 import RenderContext from './RenderContext.js';
-import { Scene } from '../../scenes/Scene.js';
-import { Camera } from '../../cameras/Camera.js';
-
-const _chainKeys = [];
-const _defaultScene = /*@__PURE__*/ new Scene();
-const _defaultCamera = /*@__PURE__*/ new Camera();
 
 /**
  * This module manages the render contexts of the renderer.
@@ -20,34 +13,25 @@ class RenderContexts {
 	constructor() {
 
 		/**
-		 * A dictionary that manages render contexts in chain maps
-		 * for each attachment state.
+		 * A dictionary that manages render contexts.
 		 *
-		 * @type {Object<string,ChainMap>}
+		 * @type {Object<string,RenderContext>}
 		 */
-		this.chainMaps = {};
+		this._renderContexts = {};
 
 	}
 
 	/**
 	 * Returns a render context for the given scene, camera and render target.
 	 *
-	 * @param {Scene} scene - The scene.
-	 * @param {Camera} camera - The camera that is used to render the scene.
 	 * @param {?RenderTarget} [renderTarget=null] - The active render target.
-	 * @param {?MRT} [mrt=null] - The active multiple render target.
+	 * @param {?MRTNode} [mrt=null] - The MRT configuration
+	 * @param {?number} [callDepth=0] - The call depth of the renderer.
 	 * @return {RenderContext} The render context.
 	 */
-	get( scene, camera, renderTarget = null, mrt = null ) {
-
-		_chainKeys[ 0 ] = scene;
-		_chainKeys[ 1 ] = camera;
+	get( renderTarget = null, mrt = null, callDepth = 0 ) {
 
-		if ( mrt !== null ) {
-
-			_chainKeys[ 2 ] = mrt;
-
-		}
+		//
 
 		let attachmentState;
 
@@ -58,63 +42,43 @@ class RenderContexts {
 		} else {
 
 			const format = renderTarget.texture.format;
+			const type = renderTarget.texture.type;
 			const count = renderTarget.textures.length;
 
-			attachmentState = `${ count }:${ format }:${ renderTarget.samples }:${ renderTarget.depthBuffer }:${ renderTarget.stencilBuffer }`;
+			attachmentState = `${ count }:${ format }:${ type }:${ renderTarget.samples }:${ renderTarget.depthBuffer }:${ renderTarget.stencilBuffer }`;
 
 		}
 
-		const chainMap = this._getChainMap( attachmentState );
+		//
+
+		const mrtState = ( mrt !== null ) ? mrt.id : 'default';
+
+		//
 
-		let renderState = chainMap.get( _chainKeys );
+		const renderStateKey = attachmentState + '-' + mrtState + '-' + callDepth;
+
+		let renderState = this._renderContexts[ renderStateKey ];
 
 		if ( renderState === undefined ) {
 
 			renderState = new RenderContext();
 
-			chainMap.set( _chainKeys, renderState );
+			 this._renderContexts[ renderStateKey ] = renderState;
 
 		}
 
-		_chainKeys.length = 0;
-
 		if ( renderTarget !== null ) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
 
 		return renderState;
 
 	}
 
-	/**
-	 * Returns a render context intended for clear operations.
-	 *
-	 * @param {?RenderTarget} [renderTarget=null] - The active render target.
-	 * @return {RenderContext} The render context.
-	 */
-	getForClear( renderTarget = null ) {
-
-		return this.get( _defaultScene, _defaultCamera, renderTarget );
-
-	}
-
-	/**
-	 * Returns a chain map for the given attachment state.
-	 *
-	 * @private
-	 * @param {string} attachmentState - The attachment state.
-	 * @return {ChainMap} The chain map.
-	 */
-	_getChainMap( attachmentState ) {
-
-		return this.chainMaps[ attachmentState ] || ( this.chainMaps[ attachmentState ] = new ChainMap() );
-
-	}
-
 	/**
 	 * Frees internal resources.
 	 */
 	dispose() {
 
-		this.chainMaps = {};
+		this._renderContexts = {};
 
 	}
 

+ 23 - 5
src/renderers/common/Renderer.js

@@ -610,6 +610,16 @@ class Renderer {
 		 */
 		this._initialized = false;
 
+		/**
+		 * The call depth of the renderer. Counts the number of
+		 * nested render calls.
+		 *
+		 * @private
+		 * @type {number}
+		 * @default - 1
+		 */
+		this._callDepth = - 1;
+
 		/**
 		 * A reference to the promise which initializes the renderer.
 		 *
@@ -695,7 +705,7 @@ class Renderer {
 				await this.compileAsync( scene, camera );
 
 				const renderList = this._renderLists.get( scene, camera );
-				const renderContext = this._renderContexts.get( scene, camera, this._renderTarget, this._mrt );
+				const renderContext = this._renderContexts.get( this._renderTarget, this._mrt );
 
 				const material = scene.overrideMaterial || object.material;
 
@@ -856,7 +866,7 @@ class Renderer {
 		if ( targetScene === null ) targetScene = scene;
 
 		const renderTarget = this._renderTarget;
-		const renderContext = this._renderContexts.get( targetScene, camera, renderTarget, this._mrt );
+		const renderContext = this._renderContexts.get( renderTarget, this._mrt );
 		const activeMipmapLevel = this._activeMipmapLevel;
 
 		const compilationPromises = [];
@@ -1359,6 +1369,8 @@ class Renderer {
 
 		//
 
+		this._callDepth ++;
+
 		const sceneRef = ( scene.isScene === true ) ? scene : _scene;
 
 		const outputRenderTarget = this._renderTarget || this._outputRenderTarget;
@@ -1384,7 +1396,7 @@ class Renderer {
 
 		//
 
-		const renderContext = this._renderContexts.get( scene, camera, renderTarget, this._mrt );
+		const renderContext = this._renderContexts.get( renderTarget, this._mrt, this._callDepth );
 
 		this._currentRenderContext = renderContext;
 		this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject;
@@ -1592,6 +1604,8 @@ class Renderer {
 
 		//
 
+		this._callDepth --;
+
 		if ( frameBufferTarget !== null ) {
 
 			this.setRenderTarget( outputRenderTarget, activeCubeFace, activeMipmapLevel );
@@ -2065,7 +2079,7 @@ class Renderer {
 
 			const renderTargetData = this._textures.get( renderTarget );
 
-			renderContext = this._renderContexts.getForClear( renderTarget );
+			renderContext = this._renderContexts.get( renderTarget );
 			renderContext.textures = renderTargetData.textures;
 			renderContext.depthTexture = renderTargetData.depthTexture;
 			renderContext.width = renderTargetData.width;
@@ -2074,7 +2088,11 @@ class Renderer {
 			renderContext.depth = renderTarget.depthBuffer;
 			renderContext.stencil = renderTarget.stencilBuffer;
 			// #30329
-			renderContext.clearColorValue = this.backend.getClearColor();
+			const color = this.backend.getClearColor();
+			renderContext.clearColorValue.r = color.r;
+			renderContext.clearColorValue.g = color.g;
+			renderContext.clearColorValue.b = color.b;
+			renderContext.clearColorValue.a = color.a;
 			renderContext.activeCubeFace = this.getActiveCubeFace();
 			renderContext.activeMipmapLevel = this.getActiveMipmapLevel();
 

粤ICP备19079148号