diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index 86ceaddadbd631..a549230715668e 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -170,7 +170,17 @@ class ObjectLoader extends Loader { const text = await loader.loadAsync( url, onProgress ); - const json = JSON.parse( text ); + let json; + + try { + + json = JSON.parse( text ); + + } catch ( e ) { + + throw new Error( 'ObjectLoader: Can\'t parse ' + url + '. ' + e.message ); + + } const metadata = json.metadata; diff --git a/src/nodes/accessors/InstanceNode.js b/src/nodes/accessors/InstanceNode.js index 53e81015bad740..7ba8f36dabf080 100644 --- a/src/nodes/accessors/InstanceNode.js +++ b/src/nodes/accessors/InstanceNode.js @@ -301,11 +301,9 @@ class InstanceNode extends Node { } else { - // WebGPU has a 64kb UBO limit, WebGL 2 ensures only 16KB; fallback to attributes if a certain count is exceeded + const uniformBufferSize = count * 16 * 4; // count * 16 components * 4 bytes (float) - const limit = ( builder.renderer.backend.isWebGPUBackend === true ) ? 1000 : 250; - - if ( count <= limit ) { + if ( uniformBufferSize <= builder.getUniformBufferLimit() ) { instanceMatrixNode = buffer( instanceMatrix.array, 'mat4', Math.max( count, 1 ) ).element( instanceIndex ); diff --git a/src/nodes/core/NodeBuilder.js b/src/nodes/core/NodeBuilder.js index 48425d7863316b..3252d677294be5 100644 --- a/src/nodes/core/NodeBuilder.js +++ b/src/nodes/core/NodeBuilder.js @@ -829,6 +829,17 @@ class NodeBuilder { } + /** + * Returns the maximum number of bytes available for uniform buffers. + * + * @return {number} The maximum number of bytes available for uniform buffers. + */ + getUniformBufferLimit() { + + return 16384; + + } + /** * Adds the given node to the internal node chain. * This is used to check recursive calls in node-graph. diff --git a/src/nodes/geometry/RangeNode.js b/src/nodes/geometry/RangeNode.js index 2397f025dd4d15..e49ba624eb0a36 100644 --- a/src/nodes/geometry/RangeNode.js +++ b/src/nodes/geometry/RangeNode.js @@ -168,8 +168,9 @@ class RangeNode extends Node { } const nodeType = this.getNodeType( builder ); + const uniformBufferSize = object.count * 4 * 4; // count * 4 components * 4 bytes (float) - if ( object.count <= 4096 ) { + if ( uniformBufferSize <= builder.getUniformBufferLimit() ) { output = buffer( array, 'vec4', object.count ).element( instanceIndex ).convert( nodeType ); diff --git a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js index e6deaad7a3420f..be15c8f9d2f99e 100644 --- a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +++ b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js @@ -1307,6 +1307,18 @@ ${ flowData.code } } + /** + * Returns the maximum number of bytes available for uniform buffers. + * + * @return {number} The maximum number of bytes available for uniform buffers. + */ + getUniformBufferLimit() { + + const gl = this.renderer.backend.gl; + return gl.getParameter( gl.MAX_UNIFORM_BLOCK_SIZE ); + + } + /** * Enables hardware clipping. * diff --git a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js index 89736ff30c7ae9..08824951269991 100644 --- a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -2143,7 +2143,6 @@ ${ flowData.code } } - /** * Returns the WGSL type of the given node data type. * @@ -2186,6 +2185,17 @@ ${ flowData.code } } + /** + * Returns the maximum uniform buffer size limit. + * + * @return {number} The maximum uniform buffer size in bytes. + */ + getUniformBufferLimit() { + + return this.renderer.backend.device.limits.maxUniformBufferBindingSize; + + } + /** * Returns the native shader method name for a given generic name. *