Custom shaders let you add unique effects to your scenes using GLSL (OpenGL Shading Language) in Three.js. Let’s create a basic shader that animates a wave effect.
Step 1: Set Up Three.js
Create a scene with a camera, renderer, and a mesh:
import * as THREE from 'three'; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5;
Step 2: Write Your Shaders
Vertex Shader (wave effect):
varying vec2 vUv;
uniform float time;
void main() {
vUv = uv;
vec3 pos = position;
pos.y += sin(pos.x * 5.0 + time) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
Fragment Shader (color gradient):
precision mediump float;
varying vec2 vUv;
void main() {
vec3 color = vec3(vUv, 1.0);
gl_FragColor = vec4(color, 1.0);
}
Step 3: Create Shader Material and Mesh
Load the shaders into ShaderMaterial:
const uniforms = { time: { value: 0.0 } };
const material = new THREE.ShaderMaterial({
uniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
});
const geometry = new THREE.PlaneGeometry(2, 2, 32, 32);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Step 4: Animate
Update the time uniform in the animation loop for an animated wave:
function animate() {
uniforms.time.value += 0.05;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
Summary
This setup applies a basic sine wave to the mesh and animates it over time. You can further customize it by adjusting the wave frequency or adding color effects in the fragment sha