瀏覽代碼

fix batching before instancing and add multidraw instance support (#27950)

Renaud Rohlinger 1 年之前
父節點
當前提交
70aed3da4c

+ 4 - 4
examples/jsm/nodes/materials/NodeMaterial.js

@@ -205,15 +205,15 @@ class NodeMaterial extends ShaderMaterial {
 
 		}
 
-		if ( ( object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true ) && builder.isAvailable( 'instance' ) === true ) {
+		if ( object.isBatchedMesh ) {
 
-			instance( object ).append();
+			batch( object ).append();
 
 		}
 
-		if ( object.isBatchedMesh ) {
+		if ( ( object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true ) && builder.isAvailable( 'instance' ) === true ) {
 
-			batch( object ).append();
+			instance( object ).append();
 
 		}
 

+ 18 - 1
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -699,7 +699,24 @@ class WebGLBackend extends Backend {
 
 		if ( object.isBatchedMesh ) {
 
-			renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
+			if ( instanceCount > 1 ) {
+
+				// TODO: Better support with InstancedBatchedMesh
+				if ( object._multiDrawInstances === undefined ) {
+
+					object._multiDrawInstances = new Int32Array( object._maxGeometryCount );
+
+				}
+
+				object._multiDrawInstances.fill( instanceCount );
+
+				renderer.renderMultiDrawInstances( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances );
+
+			} else {
+
+				renderer.renderMultiDraw( object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount );
+
+			}
 
 		} else if ( instanceCount > 1 ) {
 

+ 42 - 0
examples/jsm/renderers/webgl/WebGLBufferRenderer.js

@@ -91,6 +91,48 @@ class WebGLBufferRenderer {
 
 	}
 
+	renderMultiDrawInstances( starts, counts, drawCount, primcount ) {
+
+		const { extensions, mode, object, info } = this;
+
+		if ( drawCount === 0 ) return;
+
+		const extension = extensions.get( 'WEBGL_multi_draw' );
+
+		if ( extension === null ) {
+
+			for ( let i = 0; i < drawCount; i ++ ) {
+
+				this.renderInstances( starts[ i ], counts[ i ], primcount[ i ] );
+
+			}
+
+		} else {
+
+			if ( this.index !== 0 ) {
+
+				extension.multiDrawElementsInstancedWEBGL( mode, counts, 0, this.type, starts, 0, primcount, 0, drawCount );
+
+			} else {
+
+				extension.multiDrawArraysInstancedWEBGL( mode, starts, 0, counts, 0, primcount, 0, drawCount );
+
+			}
+
+			let elementCount = 0;
+
+			for ( let i = 0; i < drawCount; i ++ ) {
+
+				elementCount += counts[ i ];
+
+			}
+
+			info.update( object, elementCount, mode, primcount );
+
+		}
+
+	}
+
 	//
 
 }