From 8687381d9e5edf0be14db2ef239c0a5eaddf5bfa Mon Sep 17 00:00:00 2001 From: Renaud Rohlinger Date: Sat, 29 Nov 2025 22:55:03 +0900 Subject: [PATCH 1/2] WebGPUBackend: Add support indirectOffset based on IndirectStorageBufferAttribute count (#32413) --- src/core/BufferGeometry.js | 6 +++--- src/renderers/common/RenderObject.js | 2 +- src/renderers/webgpu/WebGPUBackend.js | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/core/BufferGeometry.js b/src/core/BufferGeometry.js index 5cb81ca84fc96c..c0554c06e4c105 100644 --- a/src/core/BufferGeometry.js +++ b/src/core/BufferGeometry.js @@ -112,11 +112,11 @@ class BufferGeometry extends EventDispatcher { this.indirect = null; /** - * The offset, in bytes, into the indirect drawing buffer where the value data begins. + * The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. * * Can only be used with {@link WebGPURenderer} and a WebGPU backend. * - * @type {number} + * @type {number|Array} * @default 0 */ this.indirectOffset = 0; @@ -234,7 +234,7 @@ class BufferGeometry extends EventDispatcher { * Sets the given indirect attribute to this geometry. * * @param {BufferAttribute} indirect - The attribute holding indirect draw calls. - * @param {number} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. + * @param {number|Array} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. * @return {BufferGeometry} A reference to this instance. */ setIndirect( indirect, indirectOffset = 0 ) { diff --git a/src/renderers/common/RenderObject.js b/src/renderers/common/RenderObject.js index 4b6009b728f32d..702373ee77564e 100644 --- a/src/renderers/common/RenderObject.js +++ b/src/renderers/common/RenderObject.js @@ -447,7 +447,7 @@ class RenderObject { /** * Returns the byte offset into the indirect attribute buffer. * - * @return {number} The byte offset into the indirect attribute buffer. + * @return {number|Array} The byte offset into the indirect attribute buffer. */ getIndirectOffset() { diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index bb611073e985bd..07ff008e9a127e 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -1601,8 +1601,13 @@ class WebGPUBackend extends Backend { const buffer = this.get( indirect ).buffer; const indirectOffset = renderObject.getIndirectOffset(); + const indirectOffsets = Array.isArray( indirectOffset ) ? indirectOffset : [ indirectOffset ]; - passEncoderGPU.drawIndexedIndirect( buffer, indirectOffset ); + for ( let i = 0; i < indirectOffsets.length; i ++ ) { + + passEncoderGPU.drawIndexedIndirect( buffer, indirectOffsets[ i ] ); + + } } else { @@ -1622,8 +1627,14 @@ class WebGPUBackend extends Backend { const buffer = this.get( indirect ).buffer; const indirectOffset = renderObject.getIndirectOffset(); + const indirectOffsets = Array.isArray( indirectOffset ) ? indirectOffset : [ indirectOffset ]; + + for ( let i = 0; i < indirectOffsets.length; i ++ ) { + + passEncoderGPU.drawIndirect( buffer, indirectOffsets[ i ] ); + + } - passEncoderGPU.drawIndirect( buffer, indirectOffset ); } else { From 5fd137bb7345d5f9d72c100e3471a39350c33364 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sat, 29 Nov 2025 17:06:50 +0100 Subject: [PATCH 2/2] Light: Unify `toJSON()` implementations. (#32414) --- src/lights/DirectionalLight.js | 11 +++++++++++ src/lights/HemisphereLight.js | 10 ++++++++++ src/lights/Light.js | 10 ---------- src/lights/PointLight.js | 13 +++++++++++++ src/lights/SpotLight.js | 21 ++++++++++++++++++++- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/lights/DirectionalLight.js b/src/lights/DirectionalLight.js index bd10734dcc3457..6eb0da6b26c77c 100644 --- a/src/lights/DirectionalLight.js +++ b/src/lights/DirectionalLight.js @@ -95,6 +95,17 @@ class DirectionalLight extends Light { } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.object.shadow = this.shadow.toJSON(); + data.object.target = this.target.uuid; + + return data; + + } + } export { DirectionalLight }; diff --git a/src/lights/HemisphereLight.js b/src/lights/HemisphereLight.js index a73e118c6c375e..adb332b2ec1b52 100644 --- a/src/lights/HemisphereLight.js +++ b/src/lights/HemisphereLight.js @@ -61,6 +61,16 @@ class HemisphereLight extends Light { } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.object.groundColor = this.groundColor.getHex(); + + return data; + + } + } export { HemisphereLight }; diff --git a/src/lights/Light.js b/src/lights/Light.js index 904e9cca45b0ad..47b0b5004678f8 100644 --- a/src/lights/Light.js +++ b/src/lights/Light.js @@ -76,16 +76,6 @@ class Light extends Object3D { data.object.color = this.color.getHex(); data.object.intensity = this.intensity; - if ( this.groundColor !== undefined ) data.object.groundColor = this.groundColor.getHex(); - - if ( this.distance !== undefined ) data.object.distance = this.distance; - if ( this.angle !== undefined ) data.object.angle = this.angle; - if ( this.decay !== undefined ) data.object.decay = this.decay; - if ( this.penumbra !== undefined ) data.object.penumbra = this.penumbra; - - if ( this.shadow !== undefined ) data.object.shadow = this.shadow.toJSON(); - if ( this.target !== undefined ) data.object.target = this.target.uuid; - return data; } diff --git a/src/lights/PointLight.js b/src/lights/PointLight.js index 2a65ff7cb51415..7e8255985cc769 100644 --- a/src/lights/PointLight.js +++ b/src/lights/PointLight.js @@ -111,6 +111,19 @@ class PointLight extends Light { } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.object.distance = this.distance; + data.object.decay = this.decay; + + data.object.shadow = this.shadow.toJSON(); + + return data; + + } + } export { PointLight }; diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index 856a93cb681d2b..eb93251abc651a 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -161,13 +161,32 @@ class SpotLight extends Light { this.decay = source.decay; this.target = source.target.clone(); - + this.map = source.map; this.shadow = source.shadow.clone(); return this; } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.object.distance = this.distance; + data.object.angle = this.angle; + data.object.decay = this.decay; + data.object.penumbra = this.penumbra; + + data.object.target = this.target.uuid; + + if ( this.map && this.map.isTexture ) data.object.map = this.map.toJSON( meta ).uuid; + + data.object.shadow = this.shadow.toJSON(); + + return data; + + } + } export { SpotLight };