From ffb3ef520126688a1cc948ce27eb1f60e17c5870 Mon Sep 17 00:00:00 2001 From: sunag Date: Sun, 1 Mar 2026 01:46:13 -0300 Subject: [PATCH 1/2] TSL: Fix array texture with no `.depth()` defined breaks shader compilation (#33096) --- src/nodes/accessors/TextureNode.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/nodes/accessors/TextureNode.js b/src/nodes/accessors/TextureNode.js index 9d4daf3df55c59..d6ae40867e49e6 100644 --- a/src/nodes/accessors/TextureNode.js +++ b/src/nodes/accessors/TextureNode.js @@ -553,11 +553,19 @@ class TextureNode extends UniformNode { const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null; const offsetSnippet = offsetNode ? this.generateOffset( builder, offsetNode ) : null; + let finalDepthSnippet = depthSnippet; + + if ( finalDepthSnippet === null && texture.isArrayTexture ) { + + finalDepthSnippet = '0'; + + } + const nodeVar = builder.getVarFromNode( this ); propertyName = builder.getPropertyName( nodeVar ); - let snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet, offsetSnippet ); + let snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, finalDepthSnippet, compareSnippet, gradSnippet, offsetSnippet ); if ( compareStepSnippet !== null ) { From 7bbb584ae2e47378d8199c6d934fd88c346500cb Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Sun, 1 Mar 2026 05:47:03 +0100 Subject: [PATCH 2/2] WebGPURenderer: Make device capabilities handling more consistent. (#33094) --- src/nodes/core/NodeBuilder.js | 2 +- src/renderers/common/Backend.js | 8 ---- src/renderers/common/Renderer.js | 2 +- src/renderers/webgl-fallback/WebGLBackend.js | 11 ----- .../webgl-fallback/nodes/GLSLNodeBuilder.js | 12 ----- .../webgl-fallback/utils/WebGLCapabilities.js | 25 ++++++++++ .../webgl-fallback/utils/WebGLTextureUtils.js | 2 +- src/renderers/webgpu/WebGPUBackend.js | 20 ++++---- src/renderers/webgpu/nodes/WGSLNodeBuilder.js | 11 ----- .../webgpu/utils/WebGPUCapabilities.js | 48 +++++++++++++++++++ 10 files changed, 85 insertions(+), 56 deletions(-) create mode 100644 src/renderers/webgpu/utils/WebGPUCapabilities.js diff --git a/src/nodes/core/NodeBuilder.js b/src/nodes/core/NodeBuilder.js index 360c4f5a58a01e..d475e54dd267c6 100644 --- a/src/nodes/core/NodeBuilder.js +++ b/src/nodes/core/NodeBuilder.js @@ -866,7 +866,7 @@ class NodeBuilder { */ getUniformBufferLimit() { - return 16384; + return this.renderer.backend.capabilities.getUniformBufferLimit(); } diff --git a/src/renderers/common/Backend.js b/src/renderers/common/Backend.js index 4e500f10c4384a..faf3d77a86bfec 100644 --- a/src/renderers/common/Backend.js +++ b/src/renderers/common/Backend.js @@ -604,14 +604,6 @@ class Backend { */ hasFeature( /*name*/ ) {} - /** - * Returns the maximum anisotropy texture filtering value. - * - * @abstract - * @return {number} The maximum anisotropy texture filtering value. - */ - getMaxAnisotropy() {} - /** * Returns the drawing buffer size. * diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 3e3fba59f6a759..eb40ac776b6f81 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -1778,7 +1778,7 @@ class Renderer { */ getMaxAnisotropy() { - return this.backend.getMaxAnisotropy(); + return this.backend.capabilities.getMaxAnisotropy(); } diff --git a/src/renderers/webgl-fallback/WebGLBackend.js b/src/renderers/webgl-fallback/WebGLBackend.js index 775777c21abbd3..375191e87e0047 100644 --- a/src/renderers/webgl-fallback/WebGLBackend.js +++ b/src/renderers/webgl-fallback/WebGLBackend.js @@ -2009,17 +2009,6 @@ class WebGLBackend extends Backend { } - /** - * Returns the maximum anisotropy texture filtering value. - * - * @return {number} The maximum anisotropy texture filtering value. - */ - getMaxAnisotropy() { - - return this.capabilities.getMaxAnisotropy(); - - } - /** * Copies data of the given source texture to the given destination texture. * diff --git a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js index 99158a48881e1f..974fba6112c02c 100644 --- a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +++ b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js @@ -1316,18 +1316,6 @@ ${ 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/webgl-fallback/utils/WebGLCapabilities.js b/src/renderers/webgl-fallback/utils/WebGLCapabilities.js index c311d1ff550272..e0fbbcb06218b8 100644 --- a/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +++ b/src/renderers/webgl-fallback/utils/WebGLCapabilities.js @@ -27,6 +27,14 @@ class WebGLCapabilities { */ this.maxAnisotropy = null; + /** + * This value holds the cached max uniform block size value. + * + * @type {?number} + * @default null + */ + this.maxUniformBlockSize = null; + } /** @@ -59,6 +67,23 @@ class WebGLCapabilities { } + /** + * Returns the maximum number of bytes available for uniform buffers. + * + * @return {number} The maximum number of bytes available for uniform buffers. + */ + getUniformBufferLimit() { + + if ( this.maxUniformBlockSize !== null ) return this.maxUniformBlockSize; + + const gl = this.backend.gl; + + this.maxUniformBlockSize = gl.getParameter( gl.MAX_UNIFORM_BLOCK_SIZE ); + + return this.maxUniformBlockSize; + + } + } export default WebGLCapabilities; diff --git a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js index 41846e7ec63005..b3f356e79841f4 100644 --- a/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +++ b/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js @@ -370,7 +370,7 @@ class WebGLTextureUtils { if ( texture.anisotropy > 1 ) { const extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, backend.getMaxAnisotropy() ) ); + gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, backend.capabilities.getMaxAnisotropy() ) ); } diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index e57d8cf4a5e433..bdaf4d92ca48d9 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -10,6 +10,7 @@ import Backend from '../common/Backend.js'; import WebGPUUtils from './utils/WebGPUUtils.js'; import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; +import WebGPUCapabilities from './utils/WebGPUCapabilities.js'; import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; @@ -116,6 +117,14 @@ class WebGPUBackend extends Backend { */ this.bindingUtils = new WebGPUBindingUtils( this ); + /** + * A reference to a backend module holding device capability related + * utility functions. + * + * @type {WebGPUCapabilities} + */ + this.capabilities = new WebGPUCapabilities( this ); + /** * A reference to a backend module holding shader pipeline-related * utility functions. @@ -2293,17 +2302,6 @@ class WebGPUBackend extends Backend { // utils public - /** - * Returns the maximum anisotropy texture filtering value. - * - * @return {number} The maximum anisotropy texture filtering value. - */ - getMaxAnisotropy() { - - return 16; - - } - /** * Checks if the given feature is supported by the backend. * diff --git a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js index 12d41fe4b02837..078157a1afe587 100644 --- a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -2280,17 +2280,6 @@ ${ 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. * diff --git a/src/renderers/webgpu/utils/WebGPUCapabilities.js b/src/renderers/webgpu/utils/WebGPUCapabilities.js new file mode 100644 index 00000000000000..6184b68e46c1a9 --- /dev/null +++ b/src/renderers/webgpu/utils/WebGPUCapabilities.js @@ -0,0 +1,48 @@ +/** + * A WebGPU backend utility module for managing the device's capabilities. + * + * @private + */ +class WebGPUCapabilities { + + /** + * Constructs a new utility object. + * + * @param {WebGPUBackend} backend - The WebGPU backend. + */ + constructor( backend ) { + + /** + * A reference to the WebGPU backend. + * + * @type {WebGPUBackend} + */ + this.backend = backend; + + } + + /** + * Returns the maximum anisotropy texture filtering value. + * + * @return {number} The maximum anisotropy texture filtering value. + */ + getMaxAnisotropy() { + + return 16; + + } + + /** + * Returns the maximum number of bytes available for uniform buffers. + * + * @return {number} The maximum number of bytes available for uniform buffers. + */ + getUniformBufferLimit() { + + return this.backend.device.limits.maxUniformBufferBindingSize; + + } + +} + +export default WebGPUCapabilities;