|
|
@@ -1194,69 +1194,134 @@ class WebGPUBackend extends Backend {
|
|
|
|
|
|
// draw
|
|
|
|
|
|
- if ( object.isBatchedMesh === true ) {
|
|
|
+ const draw = () => {
|
|
|
|
|
|
- const starts = object._multiDrawStarts;
|
|
|
- const counts = object._multiDrawCounts;
|
|
|
- const drawCount = object._multiDrawCount;
|
|
|
- const drawInstances = object._multiDrawInstances;
|
|
|
+ if ( object.isBatchedMesh === true ) {
|
|
|
|
|
|
- for ( let i = 0; i < drawCount; i ++ ) {
|
|
|
+ const starts = object._multiDrawStarts;
|
|
|
+ const counts = object._multiDrawCounts;
|
|
|
+ const drawCount = object._multiDrawCount;
|
|
|
+ const drawInstances = object._multiDrawInstances;
|
|
|
|
|
|
- const count = drawInstances ? drawInstances[ i ] : 1;
|
|
|
- const firstInstance = count > 1 ? 0 : i;
|
|
|
+ for ( let i = 0; i < drawCount; i ++ ) {
|
|
|
|
|
|
- if ( hasIndex === true ) {
|
|
|
+ const count = drawInstances ? drawInstances[ i ] : 1;
|
|
|
+ const firstInstance = count > 1 ? 0 : i;
|
|
|
|
|
|
- passEncoderGPU.drawIndexed( counts[ i ], count, starts[ i ] / index.array.BYTES_PER_ELEMENT, 0, firstInstance );
|
|
|
+ if ( hasIndex === true ) {
|
|
|
+
|
|
|
+ passEncoderGPU.drawIndexed( counts[ i ], count, starts[ i ] / index.array.BYTES_PER_ELEMENT, 0, firstInstance );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ passEncoderGPU.draw( counts[ i ], count, starts[ i ], firstInstance );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if ( hasIndex === true ) {
|
|
|
+
|
|
|
+ const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams;
|
|
|
+
|
|
|
+ const indirect = renderObject.getIndirect();
|
|
|
+
|
|
|
+ if ( indirect !== null ) {
|
|
|
+
|
|
|
+ const buffer = this.get( indirect ).buffer;
|
|
|
+
|
|
|
+ passEncoderGPU.drawIndexedIndirect( buffer, 0 );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- passEncoderGPU.draw( counts[ i ], count, starts[ i ], firstInstance );
|
|
|
+ passEncoderGPU.drawIndexed( indexCount, instanceCount, firstIndex, 0, 0 );
|
|
|
|
|
|
}
|
|
|
|
|
|
+ info.update( object, indexCount, instanceCount );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const { vertexCount, instanceCount, firstVertex } = drawParams;
|
|
|
+
|
|
|
+ const indirect = renderObject.getIndirect();
|
|
|
+
|
|
|
+ if ( indirect !== null ) {
|
|
|
+
|
|
|
+ const buffer = this.get( indirect ).buffer;
|
|
|
+
|
|
|
+ passEncoderGPU.drawIndirect( buffer, 0 );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ passEncoderGPU.draw( vertexCount, instanceCount, firstVertex, 0 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ info.update( object, vertexCount, instanceCount );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- } else if ( hasIndex === true ) {
|
|
|
+ };
|
|
|
|
|
|
- const { vertexCount: indexCount, instanceCount, firstVertex: firstIndex } = drawParams;
|
|
|
+ if ( renderObject.camera.isArrayCamera ) {
|
|
|
|
|
|
- const indirect = renderObject.getIndirect();
|
|
|
+ const cameraData = this.get( renderObject.camera );
|
|
|
+ const cameras = renderObject.camera.cameras;
|
|
|
|
|
|
- if ( indirect !== null ) {
|
|
|
+ if ( cameraData.indexesGPU === undefined ) {
|
|
|
|
|
|
- const buffer = this.get( indirect ).buffer;
|
|
|
+ const cameraIndex = renderObject.getBindingGroup( 'cameraIndex' );
|
|
|
+ const bindingsData = this.get( cameraIndex );
|
|
|
+ const indexesGPU = [];
|
|
|
|
|
|
- passEncoderGPU.drawIndexedIndirect( buffer, 0 );
|
|
|
+ const data = new Uint32Array( [ 0, 0, 0, 0 ] );
|
|
|
|
|
|
- } else {
|
|
|
+ for ( let i = 0, len = cameras.length; i < len; i ++ ) {
|
|
|
+
|
|
|
+ data[ 0 ] = i;
|
|
|
|
|
|
- passEncoderGPU.drawIndexed( indexCount, instanceCount, firstIndex, 0, 0 );
|
|
|
+ const bindGroupIndex = this.bindingUtils.createBindGroupIndex( data, bindingsData.layout );
|
|
|
+
|
|
|
+ indexesGPU.push( bindGroupIndex );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ cameraData.indexesGPU = indexesGPU; // TODO: Create a global library for this
|
|
|
+ cameraData.cameraIndex = cameraIndex;
|
|
|
|
|
|
}
|
|
|
|
|
|
- info.update( object, indexCount, instanceCount );
|
|
|
+ const pixelRatio = this.renderer.getPixelRatio();
|
|
|
|
|
|
- } else {
|
|
|
+ for ( let i = 0, len = cameras.length; i < len; i ++ ) {
|
|
|
|
|
|
- const { vertexCount, instanceCount, firstVertex } = drawParams;
|
|
|
+ const subCamera = cameras[ i ];
|
|
|
|
|
|
- const indirect = renderObject.getIndirect();
|
|
|
+ if ( object.layers.test( subCamera.layers ) ) {
|
|
|
|
|
|
- if ( indirect !== null ) {
|
|
|
+ const vp = subCamera.viewport;
|
|
|
|
|
|
- const buffer = this.get( indirect ).buffer;
|
|
|
+ passEncoderGPU.setViewport(
|
|
|
+ Math.floor( vp.x * pixelRatio ),
|
|
|
+ Math.floor( vp.y * pixelRatio ),
|
|
|
+ Math.floor( vp.width * pixelRatio ),
|
|
|
+ Math.floor( vp.height * pixelRatio ),
|
|
|
+ context.viewportValue.minDepth,
|
|
|
+ context.viewportValue.maxDepth
|
|
|
+ );
|
|
|
|
|
|
- passEncoderGPU.drawIndirect( buffer, 0 );
|
|
|
+ passEncoderGPU.setBindGroup( cameraData.cameraIndex.index, cameraData.indexesGPU[ i ] );
|
|
|
|
|
|
- } else {
|
|
|
+ draw();
|
|
|
|
|
|
- passEncoderGPU.draw( vertexCount, instanceCount, firstVertex, 0 );
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
- info.update( object, vertexCount, instanceCount );
|
|
|
+ } else {
|
|
|
+
|
|
|
+ draw();
|
|
|
|
|
|
}
|
|
|
|