Hello people,
I want to change color of some shaders when the theme of the website change (Light and Dark). I read how to that but I am not sure if I implemented it correctly.
Unfortunately, I can’t get the shader to work with Drei, so I’m using a “manual implementation”.
This is my functional component where I defined on of my 3d object.
export default function Sphere() {
const material = useRef<ShaderMaterial>(null!);
const [texture1, texture2] = useTexture(....);
const colors = useThemeColors();
const uniforms = useMemo(() => ({
uniforms: {
uMap: {
value: texture1,
},
tPerlin: {
value: texture2,
},
uColor: {
value: null,
},
uColorLight: {
value: null,
},
}
}), [tex, perlinTex]);
useEffect(() => {
if (!material.current) {
return;
}
material.current.uniforms.uColor.value = colors.sphere.uColor;
material.current.uniforms.uColorLight.value = colors.sphere.uColorLight;
}, [colors.sphere.uColor, colors.sphere.uColorLight]);
return (
<group>
<mesh rotation={[0, -Math.PI / 2, 0]}>
<sphereGeometry args={[100, 50, 50]} />
<shaderMaterial
ref={material}
{...uniforms}
vertexShader={vertex}
fragmentShader={fragment}
/>
</mesh>
</group>
);
};
With const colors = useThemeColors();
I am getting the right color based on the actual theme selected. It is just an object with some Color defined.
I read about “stable reference” regard uniforms, so does it make sense to use null
for uColor
and uColorLight
? I do that because if I use color returned by the useThemeColors
in the useMemo
it does not works (colors do not update upon switch theme).
To update color and so uniforms
useEffect()` is the way?
Thanks in advance for your answers.