I’m new to three.js and trying to add custom shader to the Water2.js for more realistic feel but I’m getting error while adding the shader. The current shader is a demo shader
import { useFrame, useLoader } from "@react-three/fiber";
import { useEffect, useRef } from "react";
import * as THREE from "three";
import { Water2 } from "three/examples/jsm/Addons.js";
const WaterEx = () => {
const waterRef = useRef<THREE.Group>(null);
const waterNormals = useLoader(
THREE.TextureLoader,
"https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/waternormals.jpg"
);
const customShader = {
uniforms: {
time: { value: 0.0 },
customColor: { value: new THREE.Color(0x001e0f) },
},
vertexShader: `
uniform float time;
varying vec3 vWorldPosition;
void main() {
vWorldPosition = position + normal * sin(time + position.x * 0.1) * 0.5;
gl_Position = projectionMatrix * modelViewMatrix * vec4(vWorldPosition, 1.0);
}
`,
fragmentShader: `
uniform vec3 customColor;
varying vec3 vWorldPosition;
void main() {
gl_FragColor = vec4(customColor * abs(vWorldPosition.y), 1.0);
}
`,
};
useEffect(() => {
if (waterRef.current) {
waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;
const waterGeometry = new THREE.PlaneGeometry(100, 100);
const water = new Water2(waterGeometry, {
color: 0xffffff,
scale: 4,
flowDirection: new THREE.Vector2(1, 1),
textureWidth: 1024,
textureHeight: 1024,
normalMap0: waterNormals,
normalMap1: waterNormals,
shader: customShader,
});
water.rotation.x = -Math.PI / 2; // Rotate to lay flat
waterRef.current.add(water);
return () => {
waterGeometry.dispose();
};
}
}, []);
useFrame(() => {
if (waterRef.current) {
const water = waterRef.current.children[0] as Water2;
water.material.uniforms["time"].value -= 0.4 / 60.0;
}
});
return <group ref={waterRef} />;
};
export default WaterEx;
Error:
Uncaught TypeError: Cannot set properties of undefined (setting 'value')
at WaterEx.tsx:40:21
chunk-NG4E3QU3.js?v=3e5ebd4f:18163 The above error occurred in the <WaterEx> component:
at WaterEx (http://localhost:5174/src/components/WaterEx.tsx?t=1737093630107:24:20)
at Suspense
at Suspense
at ErrorBoundary (http://localhost:5174/node_modules/.vite/deps/chunk-NG4E3QU3.js?v=3e5ebd4f:16546:5)
at FiberProvider (http://localhost:5174/node_modules/.vite/deps/chunk-NG4E3QU3.js?v=3e5ebd4f:18166:21)
at Provider (http://localhost:5174/node_modules/.vite/deps/chunk-NG4E3QU3.js?v=3e5ebd4f:17833:3)
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
2
chunk-NG4E3QU3.js?v=3e5ebd4f:18431 Uncaught TypeError: Cannot set properties of undefined (setting 'value')
at WaterEx.tsx:40:21
chunk-NG4E3QU3.js?v=3e5ebd4f:18163 The above error occurred in the <ForwardRef(Canvas)> component:
at Canvas (http://localhost:5174/node_modules/.vite/deps/chunk-NG4E3QU3.js?v=3e5ebd4f:18391:3)
at FiberProvider (http://localhost:5174/node_modules/.vite/deps/chunk-NG4E3QU3.js?v=3e5ebd4f:18166:21)
at CanvasWrapper
at App (http://localhost:5174/src/App.tsx?t=1737093567626:31:20)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
chunk-PJEEZAML.js?v=3e5ebd4f:19413 Uncaught TypeError: Cannot set properties of undefined (setting 'value')
at WaterEx.tsx:40:21