To properly utilize the shader material in Three.js, make sure to define the values for the uniforms variables time
and resolution
as shown below:
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
// [...]
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
For a complete example, refer to the code snippet below:
const renderer = new THREE.WebGLRenderer({
antialias: false
});
renderer.setSize(window.innerWidth, window.innerHeight, 2);
document.body.appendChild(renderer.domElement);
window.addEventListener( 'resize', function(e) {
renderer.setSize(window.innerWidth, window.innerHeight, 2);
});
const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
const material = new THREE.ShaderMaterial({
uniforms: {
time: { type: "f", value: 0.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4( position, 1.0 );
}
`,
fragmentShader: `
uniform vec2 resolution;
uniform float time;
const int AMOUNT = 12;
void main() {
vec2 coord = 20.0 * (gl_FragCoord.xy - resolution / 2.0) / min(resolution.y, resolution.x);
float len;
for (int i = 0; i < AMOUNT; i++){
len = length(vec2(coord.x, coord.y));
coord.x = coord.x - cos(coord.y + sin(len)) + cos(time / 9.0);
coord.y = coord.y + sin(coord.x + cos(len)) + sin(time / 12.0);
}
gl_FragColor = vec4(1.0, cos(len * 3.0), cos(len * 1.0), 1.0);
}
`
});
const quad = new THREE.Mesh(new THREE.PlaneBufferGeometry( 2, 2, 1, 1 ), material);
scene.add(quad);
function animate(timestamp) {
requestAnimationFrame(animate);
material.uniforms.time.value = timestamp / 1000;
material.uniforms.resolution.value.x = renderer.domElement.width;
material.uniforms.resolution.value.y = renderer.domElement.height;
renderer.render(scene, camera);
}
animate();
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dca8b4aeb9b99cecf2edefeb">[email protected]</a>/build/three.js"></script>