InstancedMesh, tweening instance colors

Hey all

I have a simple InstancedMesh with a MeshStandardMaterial that is using VertexColors. As such, I have a basic InstanceBufferAttribute for the colours of this mesh. I have some basic code to change the color of the selected instance on hover. I’m using the react-three-fiber wrapper, and my example is similar to this https://codesandbox.io/s/r3f-instanced-colors-8fo01?file=/src/index.js

This works fine. However, I don’t like the abrupt change between the colors, and I would like to smoothly interpolate between two colors while the instance is being hovered. I’ve tried to use react-spring and tweening the colours per frame without success. I feel I’m missing some understanding or approach here. Do I require a custom shader?

You need to know the original and the destination color, depending on how many you want to change, like just few specific or all at once you can use a second buffer or some color objects with js.

By using a second color attribute (but rgba) you can just patch the shader with onBeforeCompile. Adding attribute vec4 color2; to the header of the vertex shader and replacing #include <color_vertex> with:

#ifdef USE_COLOR

	vColor.xyz = mix( color.xyz, color2.xyz, color2.w );

#endif

You can individually blend each vertex color, but once it’s alpha is fully blended with 1.0 you need to swap the colors, overwriting color with color2 and set the alpha of color 2 to zero before setting the next destination color in color2 again.

If it’s just one specific color you can use a THREE.Color object, copy the current color from the attribute, lerp it to the destination (stored in another THREE.Color) and write it to the attribute again, repeating each frame till fully blended.

You can also use updateRange on the attribute to only upload that color, instead the entire buffer when setting needsUpdate. But i assume after a vertex is hovered it should blend to that hover color and back to default, moving over multiple fast means they all have some transition animation going on so you should be good with the second buffer attribute.

2 Likes

After realizing I had to obtain interpolation values in each frame, I sort of figured out a solution https://codesandbox.io/s/exciting-cdn-r70fx

It isn’t perfect, has some flicker

Hmm, this sounds like a smoother solution. I’ll try this approach