diff --git a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js index 5453b739ea081f..bbe4917eda200b 100644 --- a/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +++ b/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js @@ -360,7 +360,7 @@ ${ flowData.code } if ( node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true ) { - return shaderStage.charAt( 0 ) + '_' + node.name; + return node.name; } @@ -765,32 +765,56 @@ ${ flowData.code } } else { - const vectorType = this.getVectorType( uniform.type ); + const groupName = uniform.groupNode.name; - snippet = `${ vectorType } ${ this.getPropertyName( uniform, shaderStage ) };`; + // Check if this group has already been processed + if ( uniformGroups[ groupName ] === undefined ) { - group = true; + // Get the shared uniform group that contains uniforms from all stages + const sharedUniformGroup = this.uniformGroups[ groupName ]; - } + if ( sharedUniformGroup !== undefined ) { + + // Generate snippets for ALL uniforms in this shared group + const snippets = []; + + for ( const sharedUniform of sharedUniformGroup.uniforms ) { + + const type = sharedUniform.getType(); + const vectorType = this.getVectorType( type ); + const precision = sharedUniform.nodeUniform.node.precision; + + let uniformSnippet = `${ vectorType } ${ sharedUniform.name };`; + + if ( precision !== null ) { - const precision = uniform.node.precision; + uniformSnippet = precisionLib[ precision ] + ' ' + uniformSnippet; - if ( precision !== null ) { + } - snippet = precisionLib[ precision ] + ' ' + snippet; + snippets.push( '\t' + uniformSnippet ); + + } + + uniformGroups[ groupName ] = snippets; + + } + + } + + group = true; } - if ( group ) { + if ( ! group ) { - snippet = '\t' + snippet; + const precision = uniform.node.precision; - const groupName = uniform.groupNode.name; - const groupSnippets = uniformGroups[ groupName ] || ( uniformGroups[ groupName ] = [] ); + if ( precision !== null ) { - groupSnippets.push( snippet ); + snippet = precisionLib[ precision ] + ' ' + snippet; - } else { + } snippet = 'uniform ' + snippet; @@ -806,7 +830,7 @@ ${ flowData.code } const groupSnippets = uniformGroups[ name ]; - output += this._getGLSLUniformStruct( shaderStage + '_' + name, groupSnippets.join( '\n' ) ) + '\n'; + output += this._getGLSLUniformStruct( name, groupSnippets.join( '\n' ) ) + '\n'; } @@ -1595,24 +1619,38 @@ void main() { } else { - const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} ); - - let uniformsGroup = uniformsStage[ groupName ]; + let uniformsGroup = this.uniformGroups[ groupName ]; if ( uniformsGroup === undefined ) { - uniformsGroup = new NodeUniformsGroup( shaderStage + '_' + groupName, group ); - //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); + uniformsGroup = new NodeUniformsGroup( groupName, group ); - uniformsStage[ groupName ] = uniformsGroup; + this.uniformGroups[ groupName ] = uniformsGroup; bindings.push( uniformsGroup ); + } else { + + // Add to bindings for this stage if not already present + if ( bindings.indexOf( uniformsGroup ) === - 1 ) { + + bindings.push( uniformsGroup ); + + } + } uniformGPU = this.getNodeUniform( uniformNode, type ); - uniformsGroup.addUniform( uniformGPU ); + // Only add uniform if not already present in the group (check by name to avoid duplicates across stages) + const uniformName = uniformGPU.name; + const alreadyExists = uniformsGroup.uniforms.some( u => u.name === uniformName ); + + if ( ! alreadyExists ) { + + uniformsGroup.addUniform( uniformGPU ); + + } } diff --git a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js index ed7a761e7fbc76..828c2062ce1980 100644 --- a/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +++ b/src/renderers/webgpu/nodes/WGSLNodeBuilder.js @@ -1022,24 +1022,42 @@ class WGSLNodeBuilder extends NodeBuilder { } else { - const uniformsStage = this.uniformGroups[ shaderStage ] || ( this.uniformGroups[ shaderStage ] = {} ); - - let uniformsGroup = uniformsStage[ groupName ]; + let uniformsGroup = this.uniformGroups[ groupName ]; if ( uniformsGroup === undefined ) { uniformsGroup = new NodeUniformsGroup( groupName, group ); uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); - uniformsStage[ groupName ] = uniformsGroup; + this.uniformGroups[ groupName ] = uniformsGroup; bindings.push( uniformsGroup ); + } else { + + // Update visibility to include this shader stage (bitwise OR) + uniformsGroup.setVisibility( uniformsGroup.getVisibility() | gpuShaderStageLib[ shaderStage ] ); + + // Add to bindings for this stage if not already present + if ( bindings.indexOf( uniformsGroup ) === - 1 ) { + + bindings.push( uniformsGroup ); + + } + } uniformGPU = this.getNodeUniform( uniformNode, type ); - uniformsGroup.addUniform( uniformGPU ); + // Only add uniform if not already present in the group (check by name to avoid duplicates across stages) + const uniformName = uniformGPU.name; + const alreadyExists = uniformsGroup.uniforms.some( u => u.name === uniformName ); + + if ( ! alreadyExists ) { + + uniformsGroup.addUniform( uniformGPU ); + + } } @@ -1839,16 +1857,36 @@ ${ flowData.code } } else { - const vectorType = this.getType( this.getVectorType( uniform.type ) ); const groupName = uniform.groupNode.name; - const group = uniformGroups[ groupName ] || ( uniformGroups[ groupName ] = { - index: uniformIndexes.binding ++, - id: uniformIndexes.group, - snippets: [] - } ); + // Check if this group has already been processed + if ( uniformGroups[ groupName ] === undefined ) { - group.snippets.push( `\t${ uniform.name } : ${ vectorType }` ); + // Get the shared uniform group that contains uniforms from all stages + const sharedUniformGroup = this.uniformGroups[ groupName ]; + + if ( sharedUniformGroup !== undefined ) { + + // Generate snippets for ALL uniforms in this shared group + const snippets = []; + + for ( const sharedUniform of sharedUniformGroup.uniforms ) { + + const type = sharedUniform.getType(); + const vectorType = this.getType( this.getVectorType( type ) ); + snippets.push( `\t${ sharedUniform.name } : ${ vectorType }` ); + + } + + uniformGroups[ groupName ] = { + index: uniformIndexes.binding ++, + id: uniformIndexes.group, + snippets: snippets + }; + + } + + } }