Parcourir la source

WebGPURenderer: Performance revision (#26556)

sunag il y a 1 an
Parent
commit
0b169138a9

+ 2 - 4
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;
 
 		}
 

+ 2 - 2
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 );
 
 	}
 

+ 55 - 33
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 {
 

+ 3 - 0
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 ) {

+ 2 - 2
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 );
 
 	}
 

+ 8 - 0
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;

+ 29 - 6
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;
 

+ 1 - 1
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;
 
 	}

+ 2 - 1
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 ) {
 

+ 4 - 0
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 ) );

+ 6 - 0
examples/jsm/renderers/common/Binding.js

@@ -14,6 +14,12 @@ class Binding {
 
 	}
 
+	clone() {
+
+		return Object.assign( new this.constructor(), this );
+
+	}
+
 }
 
 export default Binding;

+ 1 - 2
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 ) {
 

+ 6 - 4
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;
 
 		}

+ 6 - 2
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() );
 
 	}
 

+ 1 - 1
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 );
 

+ 1 - 1
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;
 

+ 1 - 1
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;
 

+ 2 - 2
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;
 

+ 1 - 1
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;
 

+ 43 - 9
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 ) {
 

+ 16 - 9
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: {} };
 
 	}