ShaderMaterial preventing Instance Mesh setMatrixAt from updating

The SphereInstanceMeshOutline’s instances are stuck at 0,0,0 and aren’t updating at all. I think the shader is causing an interference?

// Outlines
const outlineThickness = 0.05;
const outlineGeo = new THREE.SphereGeometry( 0.5, 32, 16 );
const outlineMesh = new THREE.ShaderMaterial( {
	vertexShader: `
		void main( ) {
			vec3 newPosition = position + normal * ${outlineThickness};
			gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1 );
		}
	`,
	fragmentShader: `
		void main( ) {
			gl_FragColor = vec4( 0.2, 0.2, 0.2, 1 );
		}
	`,
	side: THREE.BackSide
} );

SphereInstanceMeshOutline = new THREE.InstancedMesh( outlineGeo, outlineMesh, amount );
SphereInstanceMeshOutline.material.needsUpdate = true;

function updateInstance( dummy, index ) {
	dummy.updateMatrix( );
	SphereInstanceMeshOutline.setMatrixAt( index, object.matrix );
	
	SphereInstanceMeshOutline.instanceMatrix.needsUpdate = true;
}

When I try to replace the ShaderMaterial to a simple MeshStandardMaterial for testing purposes, the instances positions update normally

Your shader needs to use the instance’s matrix or all your instances will be at the same position, see the code here.

2 Likes

Added the multiplier instanceMatrix to the gl_Position:
gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4( newPosition, 1 );

Works perfectly! Thank you very much!

1 Like