Browse Source

WebGLBindingsStates: Avoid redundant updates when using InstancedMesh. (#23653)

* Enable VAOs for instanced meshes

* VAOs cache off the position and color matrices from InstancedMeshes
Scott Nagy 3 years ago
parent
commit
98646f192b
1 changed files with 50 additions and 26 deletions
  1. 50 26
      src/renderers/webgl/WebGLBindingStates.js

+ 50 - 26
src/renderers/webgl/WebGLBindingStates.js

@@ -26,9 +26,9 @@
 
 			}
 
-			updateBuffers = needsUpdate( geometry, index );
+			updateBuffers = needsUpdate( object, geometry, program, index );
 
-			if ( updateBuffers ) saveCache( geometry, index );
+			if ( updateBuffers ) saveCache( object, geometry, program, index );
 
 		} else {
 
@@ -48,12 +48,6 @@
 
 		}
 
-		if ( object.isInstancedMesh === true ) {
-
-			updateBuffers = true;
-
-		}
-
 		if ( index !== null ) {
 
 			attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );
@@ -167,25 +161,40 @@
 
 	}
 
-	function needsUpdate( geometry, index ) {
+	function needsUpdate( object, geometry, program, index ) {
 
 		const cachedAttributes = currentState.attributes;
 		const geometryAttributes = geometry.attributes;
 
 		let attributesNum = 0;
 
-		for ( const key in geometryAttributes ) {
+		const programAttributes = program.getAttributes();
+
+		for ( const name in programAttributes ) {
+
+			const programAttribute = programAttributes[ name ];
+
+			if ( programAttribute.location >= 0 ) {
+
+				const cachedAttribute = cachedAttributes[ name ];
+				let geometryAttribute = geometryAttributes[ name ];
+
+				if ( geometryAttribute === undefined ) {
+
+					if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;
+					if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;
+
+				}
 
-			const cachedAttribute = cachedAttributes[ key ];
-			const geometryAttribute = geometryAttributes[ key ];
+				if ( cachedAttribute === undefined ) return true;
 
-			if ( cachedAttribute === undefined ) return true;
+				if ( cachedAttribute.attribute !== geometryAttribute ) return true;
 
-			if ( cachedAttribute.attribute !== geometryAttribute ) return true;
+				if ( geometryAttribute && cachedAttribute.data !== geometryAttribute.data ) return true;
 
-			if ( cachedAttribute.data !== geometryAttribute.data ) return true;
+				attributesNum ++;
 
-			attributesNum ++;
+			}
 
 		}
 
@@ -197,28 +206,43 @@
 
 	}
 
-	function saveCache( geometry, index ) {
+	function saveCache( object, geometry, program, index ) {
 
 		const cache = {};
 		const attributes = geometry.attributes;
 		let attributesNum = 0;
 
-		for ( const key in attributes ) {
+		const programAttributes = program.getAttributes();
 
-			const attribute = attributes[ key ];
+		for ( const name in programAttributes ) {
 
-			const data = {};
-			data.attribute = attribute;
+			const programAttribute = programAttributes[ name ];
+
+			if ( programAttribute.location >= 0 ) {
 
-			if ( attribute.data ) {
+				let attribute = attributes[ name ];
 
-				data.data = attribute.data;
+				if ( attribute === undefined ) {
 
-			}
+					if ( name === 'instanceMatrix' && object.instanceMatrix ) attribute = object.instanceMatrix;
+					if ( name === 'instanceColor' && object.instanceColor ) attribute = object.instanceColor;
 
-			cache[ key ] = data;
+				}
+
+				const data = {};
+				data.attribute = attribute;
+
+				if ( attribute && attribute.data ) {
 
-			attributesNum ++;
+					data.data = attribute.data;
+
+				}
+
+				cache[ name ] = data;
+
+				attributesNum ++;
+
+			}
 
 		}