Capítulo 846 de 859

Chapter 846: Three.js and Shadertoy (Manual)

Core Idea

How to port a Shadertoy fragment shader into three.js as a ShaderMaterial on a full-screen plane, understanding that Shadertoy shaders are a fun per-pixel-math puzzle rather than a performance best practice, and that Shadertoy's iResolution/iTime/fragCoord/fragColor are Shadertoy-specific conventions, not official GLSL.

Key Concepts

  • Shadertoy's constraint: given a pixel coordinate, output a color — a creative challenge, but computing color entirely per-pixel in a fragment shader is generally far slower than traditional triangle-based rendering with textures.
  • Shadertoy-specific uniforms: iResolution (canvas size) and iTime (seconds since load) aren't official GLSL — they're globals Shadertoy's runtime supplies, so porting a shader means declaring and feeding equivalent uniform values yourself.
  • Full-screen quad setup: an OrthographicCamera sized to a 2-unit plane fills the canvas exactly, giving a simple canvas for pasting in a Shadertoy fragment shader.
  • Wiring mainImage: the ported shader still defines its Shadertoy-style mainImage(out vec4 fragColor, in vec2 fragCoord) function; a small wrapper main() calls it with WebGL's real gl_FragColor and gl_FragCoord.xy.
  • Using it as a procedural texture: instead of feeding fragCoord from pixel coordinates, feeding it from three.js's own texture coordinates (uv, passed from a custom vertex shader as a varying) turns a Shadertoy function into a reusable procedural texture on ordinary geometry, not just a full-screen effect.

Code Examples

const uniforms = {
  iTime: { value: 0 },
  iResolution: { value: new THREE.Vector3() },
};
const material = new THREE.ShaderMaterial({ fragmentShader, uniforms });
// each frame:
uniforms.iResolution.value.set(canvas.width, canvas.height, 1);
uniforms.iTime.value = time;
  • What it demonstrates: supplying three.js uniforms that stand in for Shadertoy's implicit iResolution/iTime globals.

Key Takeaways

  1. Shadertoy shaders solve a fun, self-contained per-pixel puzzle — they're not generally a performant approach for production 3D scenes.
  2. iResolution, iTime, fragCoord, and fragColor are Shadertoy conventions, not part of GLSL itself; you must declare and feed them as ordinary uniforms in three.js.
  3. An OrthographicCamera plus a 2-unit plane is the standard way to fill the canvas for a ported full-screen shader.
  4. Feeding a Shadertoy function three.js's own uv texture coordinates (instead of raw pixel coordinates) turns it into a reusable procedural texture rather than a screen-filling effect.

Connects To

  • OrthographicCamera / MeshBasicMaterial / ShaderMaterial: the classes this porting technique is built on.