I’m trying to extend from the Diamonds example on the three-fiber documentation site, the diamonds on the ring are instances of an instancedMesh component. I’ve been banging my head for a day but couldn’t figure out how to set a different color for say the 3 biggest stones. I tried to replace the MeshRefractionMaterial with just meshBasicMaterial/meshPhysicalMaterial, and then the setColorAt
code in useFrame would work nicely, but it fails to set new colors with MeshRefractionMaterial, the diamonds defaults to white(more like transparent actually).
My code for the Ring component:
function Ring({ frame, diamonds, env, ...props }) {
const { nodes, materials } = useGLTF(RingModel);
const ref = useRef();
const color = useMemo(() => new THREE.Color(0xffff00), []);
let colorArray = new Float32Array(65 * 3);
for (let i = 0; i < 65; i++) {
colorArray.set([Math.random(), 0, 1], i * 3);
}
useFrame(() => {
// I wanted to set specific colors for just a few stones eventually, but for ease of testing I set them all
for (let i = 0; i < 65; i++) {
ref.current.setColorAt(i, color);
}
ref.current.instanceColor.needsUpdate = true;
});
return (
<group {...props} dispose={null}>
<mesh castShadow geometry={nodes.mesh_0.geometry}>
<meshStandardMaterial
color={frame}
roughness={0.15}
metalness={1}
envMapIntensity={1.5}
/>
</mesh>
<mesh
castShadow
geometry={nodes.mesh_9.geometry}
material={materials.WhiteMetal}
/>
<instancedMesh
castShadow
args={[nodes.Mesh_4.geometry, null, 65]}
instanceMatrix={nodes.Mesh_4.instanceMatrix}
ref={ref}
>
<instancedBufferAttribute
attach="instanceColor"
count={colorArray.length / 3}
array={colorArray}
itemSize={3}
/>
<MeshRefractionMaterial
// color={diamonds}
side={THREE.DoubleSide}
envMap={env}
aberrationStrength={0.02}
toneMapped={false}
vertexColors={false}
/>
{/* <meshPhysicalMaterial side={THREE.DoubleSide} /> */}
</instancedMesh>
</group>
);
}