diff --git a/src/extras/mini-stats/render2d.js b/src/extras/mini-stats/render2d.js index 6ea48e47cee..9e1d8bb716d 100644 --- a/src/extras/mini-stats/render2d.js +++ b/src/extras/mini-stats/render2d.js @@ -91,6 +91,7 @@ class Render2d { type: PRIMITIVE_TRIANGLES, indexed: true, base: 0, + baseVertex: 0, count: 0 }; this.quads = 0; diff --git a/src/platform/graphics/transform-feedback.js b/src/platform/graphics/transform-feedback.js index 7592105a3bf..6c97ca505a0 100644 --- a/src/platform/graphics/transform-feedback.js +++ b/src/platform/graphics/transform-feedback.js @@ -158,6 +158,7 @@ class TransformFeedback { device.draw({ type: PRIMITIVE_POINTS, base: 0, + baseVertex: 0, count: this._inputBuffer.numVertices, indexed: false }); diff --git a/src/platform/graphics/webgpu/webgpu-clear-renderer.js b/src/platform/graphics/webgpu/webgpu-clear-renderer.js index 92f1fb53d7a..63515d0a1b3 100644 --- a/src/platform/graphics/webgpu/webgpu-clear-renderer.js +++ b/src/platform/graphics/webgpu/webgpu-clear-renderer.js @@ -16,6 +16,7 @@ import { DepthState } from '../depth-state.js'; const primitive = { type: PRIMITIVE_TRISTRIP, base: 0, + baseVertex: 0, count: 4, indexed: false }; diff --git a/src/platform/graphics/webgpu/webgpu-graphics-device.js b/src/platform/graphics/webgpu/webgpu-graphics-device.js index 1841c9c8f47..7c793e9cc3d 100644 --- a/src/platform/graphics/webgpu/webgpu-graphics-device.js +++ b/src/platform/graphics/webgpu/webgpu-graphics-device.js @@ -536,6 +536,43 @@ class WebgpuGraphicsDevice extends GraphicsDevice { _uniqueLocations.clear(); } + /** + * Submits a graphical primitive to the hardware for immediate rendering. + * + * @param {object} primitive - Primitive object describing how to submit current vertex/index + * buffers. + * @param {number} primitive.type - The type of primitive to render. Can be: + * + * - {@link PRIMITIVE_POINTS} + * - {@link PRIMITIVE_LINES} + * - {@link PRIMITIVE_LINELOOP} + * - {@link PRIMITIVE_LINESTRIP} + * - {@link PRIMITIVE_TRIANGLES} + * - {@link PRIMITIVE_TRISTRIP} + * - {@link PRIMITIVE_TRIFAN} + * + * @param {number} primitive.base - The offset of the first index or vertex to dispatch in the + * draw call. + * @param {number} primitive.baseVertex - The number added to each index value before indexing into + * the vertex buffers. + * @param {number} primitive.count - The number of indices or vertices to dispatch in the draw + * call. + * @param {boolean} [primitive.indexed] - True to interpret the primitive as indexed, thereby + * using the currently set index buffer and false otherwise. + * @param {number} [numInstances] - The number of instances to render when using instancing. + * Defaults to 1. + * @param {boolean} [keepBuffers] - Optionally keep the current set of vertex / index buffers / + * VAO. This is used when rendering of multiple views, for example under WebXR. + * @example + * // Render a single, unindexed triangle + * device.draw({ + * type: pc.PRIMITIVE_TRIANGLES, + * base: 0, + * baseVertex: 0, + * count: 3, + * indexed: false + * }); + */ draw(primitive, numInstances = 1, keepBuffers) { if (this.shader.ready && !this.shader.failed) { @@ -574,7 +611,7 @@ class WebgpuGraphicsDevice extends GraphicsDevice { if (ib) { this.indexBuffer = null; passEncoder.setIndexBuffer(ib.impl.buffer, ib.impl.format); - passEncoder.drawIndexed(primitive.count, numInstances, primitive.base, 0, 0); + passEncoder.drawIndexed(primitive.count, numInstances, primitive.base, primitive.baseVertex || 0, 0); } else { passEncoder.draw(primitive.count, numInstances, primitive.base, 0); } diff --git a/src/scene/batching/batch-manager.js b/src/scene/batching/batch-manager.js index 1aad48cf211..fa473048376 100644 --- a/src/scene/batching/batch-manager.js +++ b/src/scene/batching/batch-manager.js @@ -659,7 +659,7 @@ class BatchManager { batch = new Batch(meshInstances, dynamic, batchGroupId); this._batchList.push(batch); - let indexBase, numIndices, indexData; + let indexBase, indexBaseVertex, numIndices, indexData; let verticesOffset = 0; let indexOffset = 0; let transform; @@ -738,6 +738,7 @@ class BatchManager { // index buffer if (mesh.primitive[0].indexed) { indexBase = mesh.primitive[0].base; + indexBaseVertex = mesh.primitive[0].baseVertex || 0; numIndices = mesh.primitive[0].count; // source index buffer data mapped to its format @@ -746,6 +747,8 @@ class BatchManager { } else { // non-indexed + indexBaseVertex = 0; + const primitiveType = mesh.primitive[0].type; if (primitiveType === PRIMITIVE_TRIFAN || primitiveType === PRIMITIVE_TRISTRIP) { if (mesh.primitive[0].count === 4) { @@ -760,7 +763,7 @@ class BatchManager { } for (let j = 0; j < numIndices; j++) { - indices[j + indexOffset] = indexData[indexBase + j] + verticesOffset; + indices[j + indexOffset] = indexData[indexBase + j] + indexBaseVertex + verticesOffset; } indexOffset += numIndices; diff --git a/src/scene/graphics/quad-render.js b/src/scene/graphics/quad-render.js index cfd78623b1b..7e9d4a4339d 100644 --- a/src/scene/graphics/quad-render.js +++ b/src/scene/graphics/quad-render.js @@ -14,6 +14,7 @@ import { processShader } from '../shader-lib/utils.js'; const _quadPrimitive = { type: PRIMITIVE_TRISTRIP, base: 0, + baseVertex: 0, count: 4, indexed: false }; diff --git a/src/scene/mesh.js b/src/scene/mesh.js index 1f113c16fa0..bcee0437fa5 100644 --- a/src/scene/mesh.js +++ b/src/scene/mesh.js @@ -202,14 +202,16 @@ class Mesh extends RefCountedObject { * * - `base` is the offset of the first index or vertex to dispatch in the draw call. * - `count` is the number of indices or vertices to dispatch in the draw call. + * - `baseVertex` is the number added to each index value before indexing into the vertex buffers. (available only for WebGPU and Batching) * - `indexed` specifies whether to interpret the primitive as indexed, thereby using the * currently set index buffer. * - * @type {{type: number, base: number, count: number, indexed?: boolean}[]} + * @type {{type: number, base: number, count: number, baseVertex: number, indexed?: boolean}[]} */ primitive = [{ type: 0, base: 0, + baseVertex: 0, count: 0 }]; @@ -1044,6 +1046,7 @@ class Mesh extends RefCountedObject { this.primitive[RENDERSTYLE_POINTS] = { type: PRIMITIVE_POINTS, base: 0, + baseVertex: 0, count: this.vertexBuffer ? this.vertexBuffer.numVertices : 0, indexed: false };