diff --git a/examples/jsm/nodes/accessors/ExtendedMaterialNode.js b/examples/jsm/nodes/accessors/ExtendedMaterialNode.js index b98858b4a21826..7df96664de56e5 100644 --- a/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +++ b/examples/jsm/nodes/accessors/ExtendedMaterialNode.js @@ -1,5 +1,3 @@ -// @TODO: Is this needed? Can it be moved in MaterialNode? - import MaterialNode from './MaterialNode.js'; import { materialReference } from './MaterialReferenceNode.js'; import { normalView } from './NormalNode.js'; @@ -42,7 +40,7 @@ class ExtendedMaterialNode extends MaterialNode { if ( material.normalMap ) { - node = normalMap( this.getTexture( 'normalMap' ), materialReference( 'normalScale', 'vec2' ) ); + node = normalMap( this.getTexture( builder, 'normalMap' ), materialReference( 'normalScale', 'vec2' ) ); } else if ( material.bumpMap ) { @@ -56,7 +54,7 @@ class ExtendedMaterialNode extends MaterialNode { } else if ( scope === ExtendedMaterialNode.CLEARCOAT_NORMAL ) { - node = material.clearcoatNormalMap ? normalMap( this.getTexture( 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView; + node = material.clearcoatNormalMap ? normalMap( this.getTexture( builder, 'clearcoatNormalMap' ), materialReference( 'clearcoatNormalScale', 'vec2' ) ) : normalView; } diff --git a/examples/jsm/nodes/accessors/LineMaterialNode.js b/examples/jsm/nodes/accessors/LineMaterialNode.js index db238ba50e23fb..51ec74b91e05db 100644 --- a/examples/jsm/nodes/accessors/LineMaterialNode.js +++ b/examples/jsm/nodes/accessors/LineMaterialNode.js @@ -10,9 +10,9 @@ class LineMaterialNode extends MaterialNode { } - construct( /* builder */ ) { + construct( builder ) { - return this.getFloat( this.scope ); + return this.getFloat( builder, this.scope ); } diff --git a/examples/jsm/nodes/accessors/MaterialNode.js b/examples/jsm/nodes/accessors/MaterialNode.js index 7a18ebe64067a3..9217efb905ad7c 100644 --- a/examples/jsm/nodes/accessors/MaterialNode.js +++ b/examples/jsm/nodes/accessors/MaterialNode.js @@ -3,6 +3,8 @@ import { reference } from './ReferenceNode.js'; import { materialReference } from './MaterialReferenceNode.js'; import { nodeImmutable, float } from '../shadernode/ShaderNode.js'; +const cache = new WeakMap(); + class MaterialNode extends Node { constructor( scope ) { @@ -13,29 +15,49 @@ class MaterialNode extends Node { } - getFloat( property ) { + getCache( builder, property, type ) { - //@TODO: Check if it can be cached by property name. + const material = builder.context.material; - return materialReference( property, 'float' ); + let cacheMaterial = cache.get( material ); - } + if ( cacheMaterial === undefined ) { + + cacheMaterial = {}; + + cache.set( material, cacheMaterial ); + + } + + let node = cacheMaterial[ property ]; + + if ( node === undefined ) { - getColor( property ) { + node = materialReference( property, type ); - //@TODO: Check if it can be cached by property name. + cacheMaterial[ property ] = node; - return materialReference( property, 'color' ); + } + + return node; } - getTexture( property ) { + getFloat( builder, property ) { - //@TODO: Check if it can be cached by property name. + return this.getCache( builder, property, 'float' ); + + } + + getColor( builder, property ) { + + return this.getCache( builder, property, 'color' ); + + } - const textureRefNode = materialReference( property, 'texture' ); + getTexture( builder, property ) { - return textureRefNode; + return this.getCache( builder, property, 'texture' ); } @@ -48,19 +70,19 @@ class MaterialNode extends Node { if ( scope === MaterialNode.ALPHA_TEST || scope === MaterialNode.SHININESS || scope === MaterialNode.REFLECTIVITY || scope === MaterialNode.ROTATION || scope === MaterialNode.IRIDESCENCE || scope === MaterialNode.IRIDESCENCE_IOR ) { - node = this.getFloat( scope ); + node = this.getFloat( builder, scope ); } else if ( scope === MaterialNode.SPECULAR_COLOR ) { - node = this.getColor( 'specular' ); + node = this.getColor( builder, 'specular' ); } else if ( scope === MaterialNode.COLOR ) { - const colorNode = this.getColor( 'color' ); + const colorNode = this.getColor( builder, 'color' ); if ( material.map && material.map.isTexture === true ) { - node = colorNode.mul( this.getTexture( 'map' ) ); + node = colorNode.mul( this.getTexture( builder, 'map' ) ); } else { @@ -70,11 +92,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.OPACITY ) { - const opacityNode = this.getFloat( 'opacity' ); + const opacityNode = this.getFloat( builder, 'opacity' ); if ( material.alphaMap && material.alphaMap.isTexture === true ) { - node = opacityNode.mul( this.getTexture( 'alphaMap' ) ); + node = opacityNode.mul( this.getTexture( builder, 'alphaMap' ) ); } else { @@ -86,7 +108,7 @@ class MaterialNode extends Node { if ( material.specularMap && material.specularMap.isTexture === true ) { - node = this.getTexture( 'specularMap' ).r; + node = this.getTexture( builder, 'specularMap' ).r; } else { @@ -96,11 +118,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.ROUGHNESS ) { - const roughnessNode = this.getFloat( 'roughness' ); + const roughnessNode = this.getFloat( builder, 'roughness' ); if ( material.roughnessMap && material.roughnessMap.isTexture === true ) { - node = roughnessNode.mul( this.getTexture( 'roughnessMap' ).g ); + node = roughnessNode.mul( this.getTexture( builder, 'roughnessMap' ).g ); } else { @@ -110,11 +132,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.METALNESS ) { - const metalnessNode = this.getFloat( 'metalness' ); + const metalnessNode = this.getFloat( builder, 'metalness' ); if ( material.metalnessMap && material.metalnessMap.isTexture === true ) { - node = metalnessNode.mul( this.getTexture( 'metalnessMap' ).b ); + node = metalnessNode.mul( this.getTexture( builder, 'metalnessMap' ).b ); } else { @@ -124,11 +146,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.EMISSIVE ) { - const emissiveNode = this.getColor( 'emissive' ); + const emissiveNode = this.getColor( builder, 'emissive' ); if ( material.emissiveMap && material.emissiveMap.isTexture === true ) { - node = emissiveNode.mul( this.getTexture( 'emissiveMap' ) ); + node = emissiveNode.mul( this.getTexture( builder, 'emissiveMap' ) ); } else { @@ -138,11 +160,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.CLEARCOAT ) { - const clearcoatNode = this.getFloat( 'clearcoat' ); + const clearcoatNode = this.getFloat( builder, 'clearcoat' ); if ( material.clearcoatMap && material.clearcoatMap.isTexture === true ) { - node = clearcoatNode.mul( this.getTexture( 'clearcoatMap' ).r ); + node = clearcoatNode.mul( this.getTexture( builder, 'clearcoatMap' ).r ); } else { @@ -152,11 +174,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.CLEARCOAT_ROUGHNESS ) { - const clearcoatRoughnessNode = this.getFloat( 'clearcoatRoughness' ); + const clearcoatRoughnessNode = this.getFloat( builder, 'clearcoatRoughness' ); if ( material.clearcoatRoughnessMap && material.clearcoatRoughnessMap.isTexture === true ) { - node = clearcoatRoughnessNode.mul( this.getTexture( 'clearcoatRoughnessMap' ).r ); + node = clearcoatRoughnessNode.mul( this.getTexture( builder, 'clearcoatRoughnessMap' ).r ); } else { @@ -166,11 +188,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.SHEEN ) { - const sheenNode = this.getColor( 'sheenColor' ).mul( this.getFloat( 'sheen' ) ); // Move this mul() to CPU + const sheenNode = this.getColor( builder, 'sheenColor' ).mul( this.getFloat( builder, 'sheen' ) ); // Move this mul() to CPU if ( material.sheenColorMap && material.sheenColorMap.isTexture === true ) { - node = sheenNode.mul( this.getTexture( 'sheenColorMap' ).rgb ); + node = sheenNode.mul( this.getTexture( builder, 'sheenColorMap' ).rgb ); } else { @@ -180,11 +202,11 @@ class MaterialNode extends Node { } else if ( scope === MaterialNode.SHEEN_ROUGHNESS ) { - const sheenRoughnessNode = this.getFloat( 'sheenRoughness' ); + const sheenRoughnessNode = this.getFloat( builder, 'sheenRoughness' ); if ( material.sheenRoughnessMap && material.sheenRoughnessMap.isTexture === true ) { - node = sheenRoughnessNode.mul( this.getTexture( 'sheenRoughnessMap' ).a ); + node = sheenRoughnessNode.mul( this.getTexture( builder, 'sheenRoughnessMap' ).a ); } else { @@ -202,7 +224,7 @@ class MaterialNode extends Node { const iridescenceThicknessMinimum = reference( 0, 'float', material.iridescenceThicknessRange ); - node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum ); + node = iridescenceThicknessMaximum.sub( iridescenceThicknessMinimum ).mul( this.getTexture( builder, 'iridescenceThicknessMap' ).g ).add( iridescenceThicknessMinimum ); } else { diff --git a/examples/jsm/nodes/accessors/MaterialReferenceNode.js b/examples/jsm/nodes/accessors/MaterialReferenceNode.js index 0e6cf712db4fb2..d0927396dc9be3 100644 --- a/examples/jsm/nodes/accessors/MaterialReferenceNode.js +++ b/examples/jsm/nodes/accessors/MaterialReferenceNode.js @@ -1,4 +1,5 @@ import ReferenceNode from './ReferenceNode.js'; +import { NodeUpdateType } from '../core/constants.js'; import { addNodeClass } from '../core/Node.js'; import { nodeObject } from '../shadernode/ShaderNode.js'; @@ -10,6 +11,8 @@ class MaterialReferenceNode extends ReferenceNode { this.material = material; + this.updateType = NodeUpdateType.RENDER; + } construct( builder ) { diff --git a/examples/jsm/nodes/accessors/Object3DNode.js b/examples/jsm/nodes/accessors/Object3DNode.js index 9cfa4505b08664..c1cce3f9f20405 100644 --- a/examples/jsm/nodes/accessors/Object3DNode.js +++ b/examples/jsm/nodes/accessors/Object3DNode.js @@ -1,6 +1,6 @@ import Node, { addNodeClass } from '../core/Node.js'; import { NodeUpdateType } from '../core/constants.js'; -import { uniform } from '../core/UniformNode.js'; +import UniformNode from '../core/UniformNode.js'; import { nodeProxy } from '../shadernode/ShaderNode.js'; import { Vector3 } from 'three'; @@ -16,7 +16,7 @@ class Object3DNode extends Node { this.updateType = NodeUpdateType.OBJECT; - this._uniformNode = uniform( null ); + this._uniformNode = new UniformNode( null ); } diff --git a/examples/jsm/nodes/core/Node.js b/examples/jsm/nodes/core/Node.js index 2f05569b7abe09..d9dd5efa8ac590 100644 --- a/examples/jsm/nodes/core/Node.js +++ b/examples/jsm/nodes/core/Node.js @@ -32,6 +32,14 @@ class Node extends EventDispatcher { } + getSelf() { + + // Returns non-node object. + + return this.self || this; + + } + isGlobal( /*builder*/ ) { return false; diff --git a/examples/jsm/nodes/core/NodeBuilder.js b/examples/jsm/nodes/core/NodeBuilder.js index 6d2d40968ffa3a..d8ced483b8ebef 100644 --- a/examples/jsm/nodes/core/NodeBuilder.js +++ b/examples/jsm/nodes/core/NodeBuilder.js @@ -104,6 +104,20 @@ class NodeBuilder { } + createBindings() { + + const bindingsArray = []; + + for ( const binding of this.getBindings() ) { + + bindingsArray.push( binding.clone() ); + + } + + return bindingsArray; + + } + getBindings() { let bindingsArray = this.bindingsArray; @@ -128,14 +142,26 @@ class NodeBuilder { addNode( node ) { - if ( this.nodes.indexOf( node ) === - 1 ) { + if ( this.nodes.includes( node ) === false ) { + + this.nodes.push( node ); + + this.setHashNode( node, node.getHash( this ) ); + + } + + } + + buildUpdateNodes() { + + for ( const node of this.nodes ) { const updateType = node.getUpdateType(); const updateBeforeType = node.getUpdateBeforeType(); if ( updateType !== NodeUpdateType.NONE ) { - this.updateNodes.push( node ); + this.updateNodes.push( node.getSelf() ); } @@ -145,10 +171,6 @@ class NodeBuilder { } - this.nodes.push( node ); - - this.setHashNode( node, node.getHash( this ) ); - } } @@ -940,6 +962,7 @@ class NodeBuilder { // stage 4: build code for a specific output this.buildCode(); + this.buildUpdateNodes(); return this; diff --git a/examples/jsm/nodes/core/NodeUniform.js b/examples/jsm/nodes/core/NodeUniform.js index 5dc7dc0948557e..7733acd8e717eb 100644 --- a/examples/jsm/nodes/core/NodeUniform.js +++ b/examples/jsm/nodes/core/NodeUniform.js @@ -6,7 +6,7 @@ class NodeUniform { this.name = name; this.type = type; - this.node = node; + this.node = node.getSelf(); this.needsUpdate = needsUpdate; } diff --git a/examples/jsm/nodes/materials/NodeMaterial.js b/examples/jsm/nodes/materials/NodeMaterial.js index 169b61c87adf16..e68af4dd8e4c69 100644 --- a/examples/jsm/nodes/materials/NodeMaterial.js +++ b/examples/jsm/nodes/materials/NodeMaterial.js @@ -16,6 +16,7 @@ import { lightsWithoutWrap } from '../lighting/LightsNode.js'; import { mix, dFdx, dFdy } from '../math/MathNode.js'; import { float, vec3, vec4 } from '../shadernode/ShaderNode.js'; import AONode from '../lighting/AONode.js'; +import { lightingContext } from '../lighting/LightingContextNode.js'; import EnvironmentNode from '../lighting/EnvironmentNode.js'; const NodeMaterials = new Map(); @@ -290,7 +291,7 @@ class NodeMaterial extends ShaderMaterial { const lightingModelNode = this.constructLightingModel( builder ); - outgoingLightNode = lightsNode.lightingContext( lightingModelNode, backdropNode, backdropAlphaNode ); + outgoingLightNode = lightingContext( lightsNode, lightingModelNode, backdropNode, backdropAlphaNode ); } else if ( backdropNode !== null ) { diff --git a/examples/jsm/nodes/shadernode/ShaderNode.js b/examples/jsm/nodes/shadernode/ShaderNode.js index f6a6b70be8652e..53c6becd343efc 100644 --- a/examples/jsm/nodes/shadernode/ShaderNode.js +++ b/examples/jsm/nodes/shadernode/ShaderNode.js @@ -37,6 +37,10 @@ const shaderNodeHandler = { return ( ...params ) => nodeElement( nodeObj, ...params ); + } else if ( prop === 'self' ) { + + return node; + } else if ( prop.endsWith( 'Assign' ) && NodeElements.has( prop.slice( 0, prop.length - 'Assign'.length ) ) ) { const nodeElement = NodeElements.get( prop.slice( 0, prop.length - 'Assign'.length ) ); diff --git a/examples/jsm/renderers/common/Binding.js b/examples/jsm/renderers/common/Binding.js index 46886f759f0e84..9f60f4e41c2ecc 100644 --- a/examples/jsm/renderers/common/Binding.js +++ b/examples/jsm/renderers/common/Binding.js @@ -14,6 +14,12 @@ class Binding { } + clone() { + + return Object.assign( new this.constructor(), this ); + + } + } export default Binding; diff --git a/examples/jsm/renderers/common/Bindings.js b/examples/jsm/renderers/common/Bindings.js index 3eeaf04de0b87a..e1f0e73a789004 100644 --- a/examples/jsm/renderers/common/Bindings.js +++ b/examples/jsm/renderers/common/Bindings.js @@ -109,10 +109,9 @@ class Bindings extends DataMap { for ( const binding of bindings ) { - const isShared = binding.isShared; const isUpdated = updateMap.get( binding ) === frame; - if ( isShared && isUpdated ) continue; + if ( isUpdated ) continue; if ( binding.isUniformBuffer ) { diff --git a/examples/jsm/renderers/common/RenderList.js b/examples/jsm/renderers/common/RenderList.js index f92af2f4627100..ad4bb8a55f31e0 100644 --- a/examples/jsm/renderers/common/RenderList.js +++ b/examples/jsm/renderers/common/RenderList.js @@ -1,4 +1,4 @@ -import { lights } from '../../nodes/Nodes.js'; +import { LightsNode } from '../../nodes/Nodes.js'; function painterSortStable( a, b ) { @@ -58,12 +58,12 @@ class RenderList { this.opaque = []; this.transparent = []; - this.lightsNode = lights( [] ); + this.lightsNode = new LightsNode( [] ); this.lightsArray = []; } - init() { + begin() { this.renderItemsIndex = 0; @@ -166,7 +166,9 @@ class RenderList { renderItem.object = null; renderItem.geometry = null; renderItem.material = null; - renderItem.program = null; + renderItem.groupOrder = null; + renderItem.renderOrder = null; + renderItem.z = null; renderItem.group = null; } diff --git a/examples/jsm/renderers/common/RenderObject.js b/examples/jsm/renderers/common/RenderObject.js index 2054d87ea439d6..32d0ef29f7d1ab 100644 --- a/examples/jsm/renderers/common/RenderObject.js +++ b/examples/jsm/renderers/common/RenderObject.js @@ -23,11 +23,15 @@ export default class RenderObject { this.pipeline = null; this.vertexBuffers = null; + this._nodeBuilder = null; + this._bindings = null; this._materialVersion = - 1; this._materialCacheKey = ''; this.onDispose = null; + this.isRenderObject = true; + this.onMaterialDispose = () => { this.dispose(); @@ -40,13 +44,13 @@ export default class RenderObject { getNodeBuilder() { - return this._nodes.getForRender( this ); + return this._nodeBuilder || ( this._nodeBuilder = this._nodes.getForRender( this ) ); } getBindings() { - return this.getNodeBuilder().getBindings(); + return this._bindings || ( this._bindings = this.getNodeBuilder().createBindings() ); } diff --git a/examples/jsm/renderers/common/Renderer.js b/examples/jsm/renderers/common/Renderer.js index 77e703d748d5ed..91e1e77cf7b29b 100644 --- a/examples/jsm/renderers/common/Renderer.js +++ b/examples/jsm/renderers/common/Renderer.js @@ -258,7 +258,7 @@ class Renderer { _frustum.setFromProjectionMatrix( _projScreenMatrix, coordinateSystem ); const renderList = this._renderLists.get( scene, camera ); - renderList.init(); + renderList.begin(); this._projectObject( scene, camera, 0, renderList ); diff --git a/examples/jsm/renderers/common/SampledTexture.js b/examples/jsm/renderers/common/SampledTexture.js index 515f132d6ea7f9..268decc1151302 100644 --- a/examples/jsm/renderers/common/SampledTexture.js +++ b/examples/jsm/renderers/common/SampledTexture.js @@ -11,7 +11,7 @@ class SampledTexture extends Binding { this.id = id ++; this.texture = texture; - this.version = texture.version; + this.version = texture ? texture.version : 0; this.isSampledTexture = true; diff --git a/examples/jsm/renderers/common/Sampler.js b/examples/jsm/renderers/common/Sampler.js index ec20eb4e0417bf..ccbdd0e5544bd2 100644 --- a/examples/jsm/renderers/common/Sampler.js +++ b/examples/jsm/renderers/common/Sampler.js @@ -7,7 +7,7 @@ class Sampler extends Binding { super( name ); this.texture = texture; - this.version = texture.version; + this.version = texture ? texture.version : 0; this.isSampler = true; diff --git a/examples/jsm/renderers/common/nodes/NodeSampledTexture.js b/examples/jsm/renderers/common/nodes/NodeSampledTexture.js index e8debe80a311dd..fa480ce94f4443 100644 --- a/examples/jsm/renderers/common/nodes/NodeSampledTexture.js +++ b/examples/jsm/renderers/common/nodes/NodeSampledTexture.js @@ -4,7 +4,7 @@ class NodeSampledTexture extends SampledTexture { constructor( name, textureNode ) { - super( name, textureNode.value ); + super( name, textureNode ? textureNode.value : null ); this.textureNode = textureNode; @@ -22,7 +22,7 @@ class NodeSampledCubeTexture extends SampledCubeTexture { constructor( name, textureNode ) { - super( name, textureNode.value ); + super( name, textureNode ? textureNode.value : null ); this.textureNode = textureNode; diff --git a/examples/jsm/renderers/common/nodes/NodeSampler.js b/examples/jsm/renderers/common/nodes/NodeSampler.js index 373e8c129724c1..0e9a243eeafbe1 100644 --- a/examples/jsm/renderers/common/nodes/NodeSampler.js +++ b/examples/jsm/renderers/common/nodes/NodeSampler.js @@ -4,7 +4,7 @@ class NodeSampler extends Sampler { constructor( name, textureNode ) { - super( name, textureNode.value ); + super( name, textureNode ? textureNode.value : null ); this.textureNode = textureNode; diff --git a/examples/jsm/renderers/common/nodes/Nodes.js b/examples/jsm/renderers/common/nodes/Nodes.js index 1e7d4bda0943b3..93dfd370603631 100644 --- a/examples/jsm/renderers/common/nodes/Nodes.js +++ b/examples/jsm/renderers/common/nodes/Nodes.js @@ -1,4 +1,5 @@ import DataMap from '../DataMap.js'; +import ChainMap from '../ChainMap.js'; import { NoToneMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three'; import { NodeFrame, cubeTexture, texture, rangeFog, densityFog, reference, toneMapping, equirectUV, viewportBottomLeft, normalWorld } from '../../../nodes/Nodes.js'; @@ -11,6 +12,15 @@ class Nodes extends DataMap { this.renderer = renderer; this.backend = backend; this.nodeFrame = new NodeFrame(); + this.cache = new ChainMap(); + + } + + getForRenderChainKey( renderObject ) { + + const { object, material, lightsNode, context } = renderObject; + + return [ object.geometry, material, lightsNode, context ]; } @@ -22,13 +32,25 @@ class Nodes extends DataMap { if ( nodeBuilder === undefined ) { - nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene ); - nodeBuilder.material = renderObject.material; - nodeBuilder.lightsNode = renderObject.lightsNode; - nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene ); - nodeBuilder.fogNode = this.getFogNode( renderObject.scene ); - nodeBuilder.toneMappingNode = this.getToneMappingNode(); - nodeBuilder.build(); + const { cache } = this; + + const chainKey = this.getForRenderChainKey( renderObject ); + + nodeBuilder = cache.get( chainKey ); + + if ( nodeBuilder === undefined ) { + + nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene ); + nodeBuilder.material = renderObject.material; + nodeBuilder.lightsNode = renderObject.lightsNode; + nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene ); + nodeBuilder.fogNode = this.getFogNode( renderObject.scene ); + nodeBuilder.toneMappingNode = this.getToneMappingNode(); + nodeBuilder.build(); + + cache.set( chainKey, nodeBuilder ); + + } renderObjectData.nodeBuilder = nodeBuilder; @@ -38,6 +60,18 @@ class Nodes extends DataMap { } + delete( object ) { + + if ( object.isRenderObject ) { + + this.cache.delete( this.getForRenderChainKey( object ) ); + + } + + return super.delete( object ); + + } + getForCompute( computeNode ) { const computeData = this.get( computeNode ); @@ -292,7 +326,7 @@ class Nodes extends DataMap { updateBefore( renderObject ) { const nodeFrame = this.getNodeFrame( renderObject ); - const nodeBuilder = this.getForRender( renderObject ); + const nodeBuilder = renderObject.getNodeBuilder(); for ( const node of nodeBuilder.updateBeforeNodes ) { @@ -307,7 +341,7 @@ class Nodes extends DataMap { updateForRender( renderObject ) { const nodeFrame = this.getNodeFrame( renderObject ); - const nodeBuilder = this.getForRender( renderObject ); + const nodeBuilder = renderObject.getNodeBuilder(); for ( const node of nodeBuilder.updateNodes ) { diff --git a/examples/jsm/renderers/webgpu/WebGPUBackend.js b/examples/jsm/renderers/webgpu/WebGPUBackend.js index 519f8008a8009b..8af05cb7f5eb2b 100644 --- a/examples/jsm/renderers/webgpu/WebGPUBackend.js +++ b/examples/jsm/renderers/webgpu/WebGPUBackend.js @@ -259,7 +259,7 @@ class WebGPUBackend extends Backend { renderContextData.descriptor = descriptor; renderContextData.encoder = encoder; renderContextData.currentPass = currentPass; - renderContextData.currentAttributesSet = {}; + renderContextData.currentSets = { attributes: {} }; // @@ -425,12 +425,19 @@ class WebGPUBackend extends Backend { const bindingsData = this.get( renderObject.getBindings() ); const contextData = this.get( context ); const pipelineGPU = this.get( pipeline ).pipeline; - const attributesSet = contextData.currentAttributesSet; + const currentSets = contextData.currentSets; // pipeline const passEncoderGPU = contextData.currentPass; - passEncoderGPU.setPipeline( pipelineGPU ); + + if ( currentSets.pipeline !== pipelineGPU ) { + + passEncoderGPU.setPipeline( pipelineGPU ); + + currentSets.pipeline = pipelineGPU; + + } // bind group @@ -447,14 +454,14 @@ class WebGPUBackend extends Backend { if ( hasIndex === true ) { - if ( attributesSet.index !== index ) { - + if ( currentSets.index !== index ) { + const buffer = this.get( index ).buffer; const indexFormat = ( index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; passEncoderGPU.setIndexBuffer( buffer, indexFormat ); - attributesSet.index = index; + currentSets.index = index; } @@ -468,12 +475,12 @@ class WebGPUBackend extends Backend { const vertexBuffer = vertexBuffers[ i ]; - if ( attributesSet[ i ] !== vertexBuffer ) { + if ( currentSets.attributes[ i ] !== vertexBuffer ) { const buffer = this.get( vertexBuffer ).buffer; passEncoderGPU.setVertexBuffer( i, buffer ); - attributesSet[ i ] = vertexBuffer; + currentSets.attributes[ i ] = vertexBuffer; } @@ -769,7 +776,7 @@ class WebGPUBackend extends Backend { if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; renderContextData.currentPass = encoder.beginRenderPass( descriptor ); - renderContextData.currentAttributesSet = {}; + renderContextData.currentSets = { attributes: {} }; }