Răsfoiți Sursa

WebGPUBindings: Improve caching.

Mugen87 4 ani în urmă
părinte
comite
9ee09d6fdc

+ 28 - 29
examples/jsm/renderers/webgpu/WebGPUBindings.js

@@ -97,7 +97,7 @@ class WebGPUBindings {
 				const array = binding.array;
 				const bufferGPU = binding.bufferGPU;
 
-				const needsBufferWrite = binding.update( array, object, camera );
+				const needsBufferWrite = binding.update( object, camera );
 
 				if ( needsBufferWrite === true ) {
 
@@ -246,12 +246,14 @@ class WebGPUBindings {
 		modelGroup.setName( 'modelUniforms' );
 		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
 		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
-		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {
+		modelGroup.setUpdateCallback( function ( object/*, camera */ ) {
 
-			array.set( object.matrixWorld.elements, 0 );
-			array.set( object.modelViewMatrix.elements, 16 );
+			let updated = false;
+
+			if ( modelGroup.updateMatrix4( object.matrixWorld, 0 ) ) updated = true;
+			if ( modelGroup.updateMatrix4( object.modelViewMatrix, 16 ) ) updated = true;
 
-			return true; // @TODO: Implement caching (return false when cache hits occurs)
+			return updated;
 
 		} );
 
@@ -261,21 +263,12 @@ class WebGPUBindings {
 		opacityGroup.setName( 'opacityUniforms' );
 		opacityGroup.setUniform( 'opacity', 1.0 );
 		opacityGroup.visibility = GPUShaderStage.FRAGMENT;
-		opacityGroup.setUpdateCallback( function ( array, object ) {
+		opacityGroup.setUpdateCallback( function ( object/*, camera */ ) {
 
 			const material = object.material;
-			const opacity = material.transparent ? material.opacity : 1.0;
-
-			let updated = false;
+			const opacity = ( material.transparent === true ) ? material.opacity : 1.0;
 
-			if ( array[ 0 ] !== opacity ) {
-
-				array[ 0 ] = opacity;
-				updated = true;
-
-			}
-
-			return updated;
+			return opacityGroup.updateNumber( opacity, 0 );
 
 		} );
 
@@ -311,12 +304,14 @@ class WebGPUBindings {
 		modelGroup.setName( 'modelUniforms' );
 		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
 		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
-		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {
+		modelGroup.setUpdateCallback( function ( object/*, camera */ ) {
 
-			array.set( object.matrixWorld.elements, 0 );
-			array.set( object.modelViewMatrix.elements, 16 );
+			let updated = false;
+
+			if ( modelGroup.updateMatrix4( object.matrixWorld, 0 ) ) updated = true;
+			if ( modelGroup.updateMatrix4( object.modelViewMatrix, 16 ) ) updated = true;
 
-			return true; // @TODO: Implement caching (return false when cache hits occurs)
+			return updated;
 
 		} );
 
@@ -341,12 +336,14 @@ class WebGPUBindings {
 		modelGroup.setName( 'modelUniforms' );
 		modelGroup.setUniform( 'modelMatrix', new Matrix4() );
 		modelGroup.setUniform( 'modelViewMatrix', new Matrix4() );
-		modelGroup.setUpdateCallback( function ( array, object/*, camera */ ) {
+		modelGroup.setUpdateCallback( function ( object/*, camera */ ) {
 
-			array.set( object.matrixWorld.elements, 0 );
-			array.set( object.modelViewMatrix.elements, 16 );
+			let updated = false;
 
-			return true; // @TODO: Implement caching (return false when cache hits occurs)
+			if ( modelGroup.updateMatrix4( object.matrixWorld, 0 ) ) updated = true;
+			if ( modelGroup.updateMatrix4( object.modelViewMatrix, 16 ) ) updated = true;
+
+			return updated;
 
 		} );
 
@@ -367,12 +364,14 @@ class WebGPUBindings {
 		cameraGroup.setName( 'cameraUniforms' );
 		cameraGroup.setUniform( 'projectionMatrix', new Matrix4() );
 		cameraGroup.setUniform( 'viewMatrix', new Matrix4() );
-		cameraGroup.setUpdateCallback( function ( array, object, camera ) {
+		cameraGroup.setUpdateCallback( function ( object, camera ) {
+
+			let updated = false;
 
-			array.set( camera.projectionMatrix.elements, 0 );
-			array.set( camera.matrixWorldInverse.elements, 16 );
+			if ( cameraGroup.updateMatrix4( camera.projectionMatrix, 0 ) ) updated = true;
+			if ( cameraGroup.updateMatrix4( camera.matrixWorldInverse, 16 ) ) updated = true;
 
-			return true; // @TODO: Implement caching (return false when cache hits occurs)
+			return updated;
 
 		} );
 

+ 156 - 0
examples/jsm/renderers/webgpu/WebGPUUniformsGroup.js

@@ -133,6 +133,162 @@ class WebGPUUniformsGroup extends WebGPUBinding {
 
 	}
 
+	updateNumber( v, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+
+		if ( a[ offset ] !== v ) {
+
+			a[ offset ] = v;
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateVector2( v, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+
+		if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y ) {
+
+			a[ offset + 0 ] = v.x;
+			a[ offset + 1 ] = v.y;
+
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateVector3( v, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+
+		if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z ) {
+
+			a[ offset + 0 ] = v.x;
+			a[ offset + 1 ] = v.y;
+			a[ offset + 2 ] = v.z;
+
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateVector4( v, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+
+		if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z || a[ offset + 4 ] !== v.w ) {
+
+			a[ offset + 0 ] = v.x;
+			a[ offset + 1 ] = v.y;
+			a[ offset + 2 ] = v.z;
+			a[ offset + 3 ] = v.z;
+
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateColor( c, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+
+		if ( a[ offset + 0 ] !== c.r || a[ offset + 1 ] !== c.g || a[ offset + 2 ] !== c.b ) {
+
+			a[ offset + 0 ] = c.r;
+			a[ offset + 1 ] = c.g;
+			a[ offset + 2 ] = c.b;
+
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateMatrix3( m, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+		const e = m.elements;
+
+		if ( a[ offset + 0 ] !== e[ 0 ] || a[ offset + 1 ] !== e[ 1 ] || a[ offset + 2 ] !== e[ 2 ] ||
+			a[ offset + 4 ] !== e[ 3 ] || a[ offset + 5 ] !== e[ 4 ] || a[ offset + 6 ] !== e[ 5 ] ||
+			a[ offset + 8 ] !== e[ 6 ] || a[ offset + 9 ] !== e[ 7 ] || a[ offset + 10 ] !== e[ 8 ] ) {
+
+			a[ offset + 0 ] = e[ 0 ];
+			a[ offset + 1 ] = e[ 1 ];
+			a[ offset + 2 ] = e[ 2 ];
+			a[ offset + 4 ] = e[ 3 ];
+			a[ offset + 5 ] = e[ 4 ];
+			a[ offset + 6 ] = e[ 5 ];
+			a[ offset + 8 ] = e[ 6 ];
+			a[ offset + 9 ] = e[ 7 ];
+			a[ offset + 10 ] = e[ 8 ];
+
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+	updateMatrix4( m, offset ) {
+
+		let updated = false;
+
+		const a = this.array;
+		const e = m.elements;
+
+		if ( arraysEqual( a, e, offset ) === false ) {
+
+			a.set( e, offset );
+			updated = true;
+
+		}
+
+		return updated;
+
+	}
+
+}
+
+function arraysEqual( a, b, offset ) {
+
+	for ( let i = 0, l = b.length; i < l; i ++ ) {
+
+		if ( a[ offset + i ] !== b[ i ] ) return false;
+
+	}
+
+	return true;
+
 }
 
 export default WebGPUUniformsGroup;