Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import { warn, error } from '../../utils.js';

let _id = 0;

const sharedNodeData = new WeakMap();

const rendererCache = new WeakMap();

const typeFromArray = new Map( [
Expand Down Expand Up @@ -2951,6 +2953,26 @@ class NodeBuilder {

}

/**
* Returns shared data object for the given node.
*
* @param {Node} node - The node to get shared data from.
* @return {Object} The shared data.
*/
getSharedDataFromNode( node ) {

let data = sharedNodeData.get( node );

if ( data === undefined ) {

data = {};

}

return data;

}

/**
* Returns a uniform representation which is later used for UBO generation and rendering.
*
Expand All @@ -2960,16 +2982,31 @@ class NodeBuilder {
*/
getNodeUniform( uniformNode, type ) {

if ( type === 'float' || type === 'int' || type === 'uint' ) return new NumberNodeUniform( uniformNode );
if ( type === 'vec2' || type === 'ivec2' || type === 'uvec2' ) return new Vector2NodeUniform( uniformNode );
if ( type === 'vec3' || type === 'ivec3' || type === 'uvec3' ) return new Vector3NodeUniform( uniformNode );
if ( type === 'vec4' || type === 'ivec4' || type === 'uvec4' ) return new Vector4NodeUniform( uniformNode );
if ( type === 'color' ) return new ColorNodeUniform( uniformNode );
if ( type === 'mat2' ) return new Matrix2NodeUniform( uniformNode );
if ( type === 'mat3' ) return new Matrix3NodeUniform( uniformNode );
if ( type === 'mat4' ) return new Matrix4NodeUniform( uniformNode );
const nodeData = this.getSharedDataFromNode( uniformNode );

let node = nodeData.cache;

if ( node === undefined ) {

if ( type === 'float' || type === 'int' || type === 'uint' ) node = new NumberNodeUniform( uniformNode );
else if ( type === 'vec2' || type === 'ivec2' || type === 'uvec2' ) node = new Vector2NodeUniform( uniformNode );
else if ( type === 'vec3' || type === 'ivec3' || type === 'uvec3' ) node = new Vector3NodeUniform( uniformNode );
else if ( type === 'vec4' || type === 'ivec4' || type === 'uvec4' ) node = new Vector4NodeUniform( uniformNode );
else if ( type === 'color' ) node = new ColorNodeUniform( uniformNode );
else if ( type === 'mat2' ) node = new Matrix2NodeUniform( uniformNode );
else if ( type === 'mat3' ) node = new Matrix3NodeUniform( uniformNode );
else if ( type === 'mat4' ) node = new Matrix4NodeUniform( uniformNode );
else {

throw new Error( `Uniform "${ type }" not implemented.` );

throw new Error( `Uniform "${type}" not declared.` );
}

nodeData.cache = node;

}

return node;

}

Expand Down
11 changes: 11 additions & 0 deletions src/renderers/common/Binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ class Binding {

}

/**
* The shader stages in which the binding's resource is visible.
*
* @return {number} The visibility bitmask.
*/
getVisibility() {

return this.visibility;

}

/**
* Clones the binding.
*
Expand Down
12 changes: 5 additions & 7 deletions src/renderers/common/Bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,14 @@ class Bindings extends DataMap {

for ( const binding of bindGroup.bindings ) {

if ( binding.isNodeUniformsGroup ) {
const updatedGroup = this.nodes.updateGroup( binding );

const updated = this.nodes.updateGroup( binding );
// every uniforms group is a uniform buffer. So if no update is required,
// we move one with the next binding. Otherwise the next if block will update the group.

// every uniforms group is a uniform buffer. So if no update is required,
// we move one with the next binding. Otherwise the next if block will update the group.
if ( updatedGroup === false ) continue;

if ( updated === false ) continue;

}
//

if ( binding.isStorageBuffer ) {

Expand Down
17 changes: 14 additions & 3 deletions src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -1531,11 +1531,22 @@ void main() {

} else if ( type === 'buffer' ) {

node.name = `NodeBuffer_${ node.id }`;
uniformNode.name = `buffer${ node.id }`;

const buffer = new NodeUniformBuffer( node, group );
buffer.name = node.name;
const sharedData = this.getSharedDataFromNode( node );

let buffer = sharedData.buffer;

if ( buffer === undefined ) {

node.name = `NodeBuffer_${ node.id }`;

buffer = new NodeUniformBuffer( node, group );
buffer.name = node.name;

sharedData.buffer = buffer;

}

bindings.push( buffer );

Expand Down
17 changes: 14 additions & 3 deletions src/renderers/webgpu/nodes/WGSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -974,10 +974,21 @@ class WGSLNodeBuilder extends NodeBuilder {

} else if ( type === 'buffer' || type === 'storageBuffer' || type === 'indirectStorageBuffer' ) {

const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer;
const sharedData = this.getSharedDataFromNode( node );

const buffer = new bufferClass( node, group );
buffer.setVisibility( gpuShaderStageLib[ shaderStage ] );
let buffer = sharedData.buffer;

if ( buffer === undefined ) {

const bufferClass = type === 'buffer' ? NodeUniformBuffer : NodeStorageBuffer;

buffer = new bufferClass( node, group );

sharedData.buffer = buffer;

}

buffer.setVisibility( buffer.getVisibility() | gpuShaderStageLib[ shaderStage ] );

bindings.push( buffer );

Expand Down