Quellcode durchsuchen

WebGPURenderer: avoid render pass/pipeline attachment mismatches (#26376)

* add support for meshPhongNodeMaterial

* add renderTarget to key for renderContexts

* use renderContext as key to locate correct renderobjects in cache

* rework to use attachment state and fix deletion path

* remove surplus :

---------

Co-authored-by: aardgoose <[email protected]>
aardgoose vor 2 Jahren
Ursprung
Commit
366d701975

+ 13 - 4
examples/jsm/renderers/common/RenderContexts.js

@@ -5,21 +5,24 @@ class RenderContexts {
 
 	constructor() {
 
-		this.renderStates = new ChainMap();
+		this.chainMaps = {};
 
 	}
 
-	get( scene, camera ) {
+	get( scene, camera, renderTarget = null ) {
 
 		const chainKey = [ scene, camera ];
+		const attachmentState = renderTarget === null ? 'default' : `${renderTarget.texture.format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`;
+
+		const chainMap = this.getChainMap( attachmentState );
 
-		let renderState = this.renderStates.get( chainKey );
+		let renderState = chainMap.get( chainKey );
 
 		if ( renderState === undefined ) {
 
 			renderState = new RenderContext();
 
-			this.renderStates.set( chainKey, renderState );
+			chainMap.set( chainKey, renderState );
 
 		}
 
@@ -27,6 +30,12 @@ class RenderContexts {
 
 	}
 
+	getChainMap( attachmentState ) {
+
+		return this.chainMaps[ attachmentState ] || ( this.chainMaps[ attachmentState ] = new ChainMap() );
+
+	}
+
 	dispose() {
 
 		this.renderStates = new ChainMap();

+ 3 - 3
examples/jsm/renderers/common/RenderObject.js

@@ -2,7 +2,7 @@ let id = 0;
 
 export default class RenderObject {
 
-	constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode ) {
+	constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext ) {
 
 		this._nodes = nodes;
 		this._geometries = geometries;
@@ -19,7 +19,7 @@ export default class RenderObject {
 		this.geometry = object.geometry;
 
 		this.attributes = null;
-		this.context = null;
+		this.context = renderContext;
 		this.pipeline = null;
 		this.vertexBuffers = null;
 
@@ -58,7 +58,7 @@ export default class RenderObject {
 
 	getChainArray() {
 
-		return [ this.object, this.material, this.scene, this.camera, this.lightsNode ];
+		return [ this.object, this.material, this.context, this.lightsNode ];
 
 	}
 

+ 6 - 6
examples/jsm/renderers/common/RenderObjects.js

@@ -17,16 +17,16 @@ class RenderObjects {
 
 	}
 
-	get( object, material, scene, camera, lightsNode, passId ) {
+	get( object, material, scene, camera, lightsNode, renderContext, passId ) {
 
 		const chainMap = this.getChainMap( passId );
-		const chainArray = [ object, material, scene, camera, lightsNode ];
+		const chainArray = [ object, material, renderContext, lightsNode ];
 
 		let renderObject = chainMap.get( chainArray );
 
 		if ( renderObject === undefined ) {
 
-			renderObject = this.createRenderObject( this.nodes, this.geometries, this.renderer, object, material, scene, camera, lightsNode, passId );
+			renderObject = this.createRenderObject( this.nodes, this.geometries, this.renderer, object, material, scene, camera, lightsNode, renderContext, passId );
 
 			chainMap.set( chainArray, renderObject );
 
@@ -39,7 +39,7 @@ class RenderObjects {
 
 				renderObject.dispose();
 
-				renderObject = this.get( object, material, scene, camera, lightsNode );
+				renderObject = this.get( object, material, scene, camera, lightsNode, renderContext );
 
 			}
 
@@ -62,11 +62,11 @@ class RenderObjects {
 
 	}
 
-	createRenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, passId ) {
+	createRenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext, passId ) {
 
 		const chainMap = this.getChainMap( passId );
 		const dataMap = this.dataMap;
-		const renderObject = new RenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode );
+		const renderObject = new RenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext );
 
 		const data = dataMap.get( renderObject );
 		data.cacheKey = renderObject.getCacheKey();

+ 2 - 3
examples/jsm/renderers/common/Renderer.js

@@ -181,8 +181,8 @@ class Renderer {
 
 		//
 
-		const renderContext = this._renderContexts.get( scene, camera );
 		const renderTarget = this._renderTarget;
+		const renderContext = this._renderContexts.get( scene, camera, renderTarget );
 		const activeCubeFace = this._activeCubeFace;
 
 		this._currentRenderContext = renderContext;
@@ -840,8 +840,7 @@ class Renderer {
 
 		//
 
-		const renderObject = this._objects.get( object, material, scene, camera, lightsNode, passId );
-		renderObject.context = this._currentRenderContext;
+		const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, passId );
 
 		//