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
358 changes: 304 additions & 54 deletions src/renderers/common/Backend.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/renderers/common/BindGroup.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
let _id = 0;

/**
* Represents a bind group.
* A bind group represents a collection of bindings and thus a collection
* or resources. Bind groups are assigned to pipelines to provide them
* with the required resources (like uniform buffers or textures).
*
* @private
*/
Expand Down
5 changes: 4 additions & 1 deletion src/renderers/common/Bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,10 @@ class Bindings extends DataMap {

const updated = this.nodes.updateGroup( binding );

if ( ! updated ) continue;
// 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 ( updated === false ) continue;

}

Expand Down
96 changes: 95 additions & 1 deletion src/renderers/common/nodes/NodeBuilderState.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,128 @@
import BindGroup from '../BindGroup.js';

/**
* This module represents the state of a node builder after it was
* used to build the nodes for a render object. The state holds the
* results of the build for further processing in the renderer.
*
* Render objects with identical cache keys share the same node builder state.
*
* @private
*/
class NodeBuilderState {

/**
* Constructs a new node builder state.
*
* @param {String?} vertexShader - The native vertex shader code.
* @param {String?} fragmentShader - The native fragment shader code.
* @param {String?} computeShader - The native compute shader code.
* @param {Array<NodeAttribute>} nodeAttributes - An array of node attributes.
* @param {Array<BindGroup>} bindings - An array of bind groups.
* @param {Array<Node>} updateNodes - An array of nodes that implement their `update()` method.
* @param {Array<Node>} updateBeforeNodes - An array of nodes that implement their `updateBefore()` method.
* @param {Array<Node>} updateAfterNodes - An array of nodes that implement their `updateAfter()` method.
* @param {NodeMaterialObserver} monitor - A node material observer.
* @param {Array<Object>} transforms - An array with transform attribute objects. Only relevant when using compute shaders with WebGL 2.
*/
constructor( vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes, updateAfterNodes, monitor, transforms = [] ) {

/**
* The native vertex shader code.
*
* @type {String}
*/
this.vertexShader = vertexShader;

/**
* The native fragment shader code.
*
* @type {String}
*/
this.fragmentShader = fragmentShader;

/**
* The native compute shader code.
*
* @type {String}
*/
this.computeShader = computeShader;

/**
* An array with transform attribute objects.
* Only relevant when using compute shaders with WebGL 2.
*
* @type {Array<Object>}
*/
this.transforms = transforms;

/**
* An array of node attributes representing
* the attributes of the shaders.
*
* @type {Array<NodeAttribute>}
*/
this.nodeAttributes = nodeAttributes;

/**
* An array of bind groups representing the uniform or storage
* buffers, texture or samplers of the shader.
*
* @type {Array<BindGroup>}
*/
this.bindings = bindings;

/**
* An array of nodes that implement their `update()` method.
*
* @type {Array<Node>}
*/
this.updateNodes = updateNodes;

/**
* An array of nodes that implement their `updateBefore()` method.
*
* @type {Array<Node>}
*/
this.updateBeforeNodes = updateBeforeNodes;

/**
* An array of nodes that implement their `updateAfter()` method.
*
* @type {Array<Node>}
*/
this.updateAfterNodes = updateAfterNodes;

/**
* A node material observer.
*
* @type {NodeMaterialObserver}
*/
this.monitor = monitor;

/**
* How often this state is used by render objects.
*
* @type {Number}
*/
this.usedTimes = 0;

}

/**
* This method is used to create a array of bind groups based
* on the existing bind groups of this state. Shared groups are
* not cloned.
*
* @return {Array<BindGroup>} A array of bind groups.
*/
createBindings() {

const bindings = [];

for ( const instanceGroup of this.bindings ) {

const shared = instanceGroup.bindings[ 0 ].groupNode.shared;
const shared = instanceGroup.bindings[ 0 ].groupNode.shared; // TODO: Is it safe to always check the first binding in the group?

if ( shared !== true ) {

Expand Down
89 changes: 89 additions & 0 deletions src/renderers/common/nodes/NodeLibrary.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,52 @@
/**
* The purpose of a node library is to assign node implementations
* to existing library features. In `WebGPURenderer` lights, materials
* which are not based on `NodeMaterial` as well as tone mapping techniques
* are implemented with node-based modules.
*
* @private
*/
class NodeLibrary {

/**
* Constructs a new node library.
*/
constructor() {

/**
* A weak map that maps lights to light nodes.
*
* @type {WeakMap<Light.constructor,AnalyticLightNode.constructor>}
*/
this.lightNodes = new WeakMap();

/**
* A map that maps materials to node materials.
*
* @type {WeakMap<String,NodeMaterial.constructor>}
*/
this.materialNodes = new Map();

/**
* A map that maps tone mapping techniques (constants)
* to tone mapping node functions.
*
* @type {WeakMap<Number,Function>}
*/
this.toneMappingNodes = new Map();

}

/**
* Returns a matching node material instance for the given material object.
*
* This method also assigns/copies the properties of the given material object
* to the node material. This is done to make sure the current material
* configuration carries over to the node version.
*
* @param {Material} material - A material.
* @return {NodeMaterial} The corresponding node material.
*/
fromMaterial( material ) {

if ( material.isNodeMaterial ) return material;
Expand All @@ -32,42 +71,85 @@ class NodeLibrary {

}

/**
* Adds a tone mapping node function for a tone mapping technique (constant).
*
* @param {Function} toneMappingNode - The tone mapping node function.
* @param {Number} toneMapping - The tone mapping.
*/
addToneMapping( toneMappingNode, toneMapping ) {

this.addType( toneMappingNode, toneMapping, this.toneMappingNodes );

}

/**
* Returns a tone mapping node function for a tone mapping technique (constant).
*
* @param {Number} toneMapping - The tone mapping.
* @return {Function?} The tone mapping node function. Returns `null` if no node function is found.
*/
getToneMappingFunction( toneMapping ) {

return this.toneMappingNodes.get( toneMapping ) || null;

}

/**
* Returns a node material class definition for a material type.
*
* @param {Sring} materialType - The material type.
* @return {NodeMaterial.constructor?} The node material class definition. Returns `null` if no node material is found.
*/
getMaterialNodeClass( materialType ) {

return this.materialNodes.get( materialType ) || null;

}

/**
* Adds a node material class definition for a given material type.
*
* @param {NodeMaterial.constructor} materialNodeClass - The node material class definition.
* @param {Sring} materialClassType - The material type.
*/
addMaterial( materialNodeClass, materialClassType ) {

this.addType( materialNodeClass, materialClassType, this.materialNodes );

}

/**
* Returns a light node class definition for a light class definition.
*
* @param {Light.constructor} light - The light class definition.
* @return {AnalyticLightNode.constructor?} The light node class definition. Returns `null` if no light node is found.
*/
getLightNodeClass( light ) {

return this.lightNodes.get( light ) || null;

}

/**
* Adds a light node class definition for a given light class definition.
*
* @param {AnalyticLightNode.constructor} lightNodeClass - The light node class definition.
* @param {Light.constructor} lightClass - The light class definition.
*/
addLight( lightNodeClass, lightClass ) {

this.addClass( lightNodeClass, lightClass, this.lightNodes );

}

/**
* Adds a node class definition for the given type to the provided type library.
*
* @param {Any} nodeClass - The node class definition.
* @param {String} type - The object type.
* @param {Map} library - The type library.
*/
addType( nodeClass, type, library ) {

if ( library.has( type ) ) {
Expand All @@ -84,6 +166,13 @@ class NodeLibrary {

}

/**
* Adds a node class definition for the given class definition to the provided type library.
*
* @param {Any} nodeClass - The node class definition.
* @param {Any} baseClass - The class definition.
* @param {WeakMap} library - The type library.
*/
addClass( nodeClass, baseClass, library ) {

if ( library.has( baseClass ) ) {
Expand Down
Loading
Loading