Shader Craft
A unified skill covering 36 GLSL shader techniques (ShaderToy-compatible) for real-time visual effects.
Invocation
/shader-dev <request>
$ARGUMENTS contains the user's request (e.g. "create a raymarched SDF scene with soft shadows").
Skill Structure
shader-dev/
├── SKILL.md # Core skill (this file)
├── techniques/ # Implementation guides (read per routing table)
│ ├── ray-marching.md # Sphere tracing with SDF
│ ├── sdf-3d.md # 3D signed distance functions
│ ├── lighting-model.md # PBR, Phong, toon shading
│ ├── procedural-noise.md # Perlin, Simplex, FBM
│ └── ... # 34 more technique files
└── reference/ # Detailed guides (read as needed)
├── ray-marching.md # Math derivations & advanced patterns
├── sdf-3d.md # Extended SDF theory
├── lighting-model.md # Lighting math deep-dive
├── procedural-noise.md # Noise function theory
└── ... # 34 more reference files
How to Use
- Read the Technique Routing Table below to identify which technique(s) match the user's request
- Read the relevant file(s) from
techniques/ — each file contains core principles, implementation steps, and complete code templates
- If you need deeper understanding (math derivations, advanced patterns), follow the reference link at the bottom of each technique file to
reference/
- Apply the WebGL2 Adaptation Rules below when generating standalone HTML pages
Technique Routing Table
| User wants to create... |
Primary technique |
Combine with |
| 3D objects / scenes from math |
ray-marching + sdf-3d |
lighting-model, shadow-techniques |
| Complex 3D shapes (booleans, blends) |
csg-boolean-operations |
sdf-3d, ray-marching |
| Infinite repeating patterns in 3D |
domain-repetition |
sdf-3d, ray-marching |
| Organic / warped shapes |
domain-warping |
procedural-noise |
| Fluid / smoke / ink effects |
fluid-simulation |
multipass-buffer |
| Particle effects (fire, sparks, snow) |
particle-system |
procedural-noise, color-palette |
| Physically-based simulations |
simulation-physics |
multipass-buffer |
| Game of Life / reaction-diffusion |
cellular-automata |
multipass-buffer, color-palette |
| Ocean / water surface |
water-ocean |
atmospheric-scattering, lighting-model |
| Terrain / landscape |
terrain-rendering |
atmospheric-scattering, procedural-noise |
| Clouds / fog / volumetric fire |
volumetric-rendering |
procedural-noise, atmospheric-scattering |
| Sky / sunset / atmosphere |
atmospheric-scattering |
volumetric-rendering |
| Realistic lighting (PBR, Phong) |
lighting-model |
shadow-techniques, ambient-occlusion |
| Shadows (soft / hard) |
shadow-techniques |
lighting-model |
| Ambient occlusion |
ambient-occlusion |
lighting-model, normal-estimation |
| Path tracing / global illumination |
path-tracing-gi |
analytic-ray-tracing, multipass-buffer |
| Precise ray-geometry intersections |
analytic-ray-tracing |
lighting-model |
| Voxel worlds (Minecraft-style) |
voxel-rendering |
lighting-model, shadow-techniques |
| Noise / FBM textures |
procedural-noise |
domain-warping |
| Tiled 2D patterns |
procedural-2d-pattern |
polar-uv-manipulation |
| Voronoi / cell patterns |
voronoi-cellular-noise |
color-palette |
| Fractals (Mandelbrot, Julia, 3D) |
fractal-rendering |
color-palette, polar-uv-manipulation |
| Color grading / palettes |
color-palette |
— |
| Bloom / tone mapping / glitch |
post-processing |
multipass-buffer |
| Multi-pass ping-pong buffers |
multipass-buffer |
— |
| Texture / sampling techniques |
texture-sampling |
— |
| Camera / matrix transforms |
matrix-transform |
— |
| Surface normals |
normal-estimation |
— |
| Polar coords / kaleidoscope |
polar-uv-manipulation |
procedural-2d-pattern |
| 2D shapes / UI from SDF |
sdf-2d |
color-palette |
| Procedural audio / music |
sound-synthesis |
— |
| SDF tricks / optimization |
sdf-tricks |
sdf-3d, ray-marching |
| Anti-aliased rendering |
anti-aliasing |
sdf-2d, post-processing |
| Depth of field / motion blur / lens effects |
camera-effects |
post-processing, multipass-buffer |
| Advanced texture mapping / no-tile textures |
texture-mapping-advanced |
terrain-rendering, texture-sampling |
| WebGL2 shader errors / debugging |
webgl-pitfalls |
— |
Technique Index
Geometry & SDF
- sdf-2d — 2D signed distance functions for shapes, UI, anti-aliased rendering
- sdf-3d — 3D signed distance functions for real-time implicit surface modeling
- csg-boolean-operations — Constructive solid geometry: union, subtraction, intersection with smooth blending
- domain-repetition — Infinite space repetition, folding, and limited tiling
- domain-warping — Distort domains with noise for organic, flowing shapes
- sdf-tricks — SDF optimization, bounding volumes, binary search refinement, hollowing, layered edges, debug visualization
Ray Casting & Lighting
- ray-marching — Sphere tracing with SDF for 3D scene rendering
- analytic-ray-tracing — Closed-form ray-primitive intersections (sphere, plane, box, torus)
- path-tracing-gi — Monte Carlo path tracing for photorealistic global illumination
- lighting-model — Phong, Blinn-Phong, PBR (Cook-Torrance), and toon shading
- shadow-techniques — Hard shadows, soft shadows (penumbra estimation), cascade shadows
- ambient-occlusion — SDF-based AO, screen-space AO approximation
- normal-estimation — Finite-difference normals, tetrahedron technique
Simulation & Physics
- fluid-simulation — Navier-Stokes fluid solver with advection, diffusion, pressure projection
- simulation-physics — GPU-based physics: springs, cloth, N-body gravity, collision
- particle-system — Stateless and stateful particle systems (fire, rain, sparks, galaxies)
- cellular-automata — Game of Life, reaction-diffusion (Turing patterns), sand simulation
Natural Phenomena
- water-ocean — Gerstner waves, FFT ocean, caustics, underwater fog
- terrain-rendering — Heightfield ray marching, FBM terrain, erosion
- atmospheric-scattering — Rayleigh/Mie scattering, god rays, SSS approximation
- volumetric-rendering — Volume ray marching for clouds, fog, fire, explosions
Procedural Generation
- procedural-noise — Value noise, Perlin, Simplex, Worley, FBM, ridged noise
- procedural-2d-pattern — Brick, hexagon, truchet, Islamic geometric patterns
- voronoi-cellular-noise — Voronoi diagrams, Worley noise, cracked earth, crystal
- fractal-rendering — Mandelbrot, Julia sets, 3D fractals (Mandelbox, Mandelbulb)
- color-palette — Cosine palettes, HSL/HSV/Oklab, dynamic color mapping
Post-Processing & Infrastructure
- post-processing — Bloom, tone mapping (ACES, Reinhard), vignette, chromatic aberration, glitch
- multipass-buffer — Ping-pong FBO setup, state persistence across frames
- texture-sampling — Bilinear, bicubic, mipmap, procedural texture lookup
- matrix-transform — Camera look-at, projection, rotation, orbit controls
- polar-uv-manipulation — Polar/log-polar coordinates, kaleidoscope, spiral mapping
- anti-aliasing — SSAA, SDF analytical AA, temporal anti-aliasing (TAA), FXAA post-process
- camera-effects — Depth of field (thin lens), motion blur, lens distortion, film grain, vignette
- texture-mapping-advanced — Biplanar mapping, texture repetition avoidance, ray differential filtering
Audio
- sound-synthesis — Procedural audio in GLSL: oscillators, envelopes, filters, FM synthesis
Debugging & Validation
- webgl-pitfalls — Common WebGL2/GLSL errors:
fragCoord, main() wrapper, function order, macro limitations, uniform null
WebGL2 Adaptation Rules
All technique files use ShaderToy GLSL style. When generating standalone HTML pages, apply these adaptations:
Shader Version & Output
- Use
canvas.getContext("webgl2")
- Shader first line:
#version 300 es, fragment shader adds precision highp float;
- Fragment shader must declare:
out vec4 fragColor;
- Vertex shader:
attribute → in, varying → out
- Fragment shader:
varying → in, gl_FragColor → fragColor, texture2D() → texture()
Fragment Coordinate
- Use
gl_FragCoord.xy instead of fragCoord (WebGL2 does not have fragCoord built-in)
// WRONG
vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.y;
// CORRECT
vec2 uv = (2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.y;
main() Wrapper for ShaderToy Templates
- ShaderToy uses
void mainImage(out vec4 fragColor, in vec2 fragCoord)
- WebGL2 requires standard
void main() entry point — always wrap mainImage:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// shader code...
fragColor = vec4(col, 1.0);
}
void main() {
mainImage(fragColor, gl_FragCoord.xy);
}
Function Declaration Order
- GLSL requires functions to be declared before use — either declare before use or reorder:
// WRONG — getAtmosphere() calls getSunDirection() before it's defined
vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Error!
vec3 getSunDirection() { return normalize(vec3(1.0)); }
// CORRECT — define callee first
vec3 getSunDirection() { return normalize(vec3(1.0)); }
vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Works
Macro Limitations
#define cannot use function calls — use const instead:
// WRONG
#define SUN_DIR normalize(vec3(0.8, 0.4, -0.6))
// CORRECT
const vec3 SUN_DIR = vec3(0.756, 0.378, -0.567); // Pre-computed normalized value
Script Tag Extraction
- When extracting shader source from
<script> tags, ensure #version is the first character — use .trim():
const fs = document.getElementById('fs').text.trim();
Common Pitfalls
- Unused uniforms: Compiler may optimize away unused uniforms, causing
gl.getUniformLocation() to return null — always use uniforms in a way the compiler cannot optimize out
- Loop indices: Use runtime constants in loops, not
#define macros in some ES versions
- Terrain functions: Functions like
terrainM(vec2) need XZ components — use terrainM(pos.xz + offset) not terrainM(pos + offset)
HTML Page Setup
When generating a standalone HTML page:
- Canvas fills the entire viewport, auto-resizes on window resize
- Page background black, no scrollbars:
body { margin: 0; overflow: hidden; background: #000; }
- Implement ShaderToy-compatible uniforms:
iTime, iResolution, iMouse, iFrame
- For multi-pass effects (Buffer A/B), use WebGL2 framebuffer + ping-pong (see multipass-buffer technique)
Common Pitfalls
JS Variable Declaration Order (TDZ — causes white screen crash)
let/const variables must be declared at the top of the <script> block, before any function that references them:
// 1. State variables FIRST
let frameCount = 0;
let startTime = Date.now();
// 2. Canvas/GL init, shader compile, FBO creation
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl2');
// ...
// 3. Functions and event bindings LAST
function resize() { /* can now safely reference frameCount */ }
function render() { /* ... */ }
window.addEventListener('resize', resize);
Reason: let/const have a Temporal Dead Zone — referencing them before declaration throws ReferenceError, causing a white screen.
GLSL Compilation Errors (self-check after writing shaders)
- Function signature mismatch: Call must exactly match definition in parameter count and types. If defined as
float fbm(vec3 p), cannot call fbm(uv) with a vec2
- Reserved words as variable names: Do not use:
patch, cast, sample, filter, input, output, common, partition, active
- Strict type matching:
vec3 x = 1.0 is illegal — use vec3 x = vec3(1.0); cannot use .z to access a vec2
- No ternary on structs: ESSL does not allow ternary operator on struct types — use
if/else instead
Performance Budget
Deployment environments may use headless software rendering with limited GPU power. Stay within these limits:
- Ray marching main loop: ≤ 128 steps
- Volume sampling / lighting inner loops: ≤ 32 steps
- FBM octaves: ≤ 6 layers
- Total nested loop iterations per pixel: ≤ 1000 (exceeding this freezes the browser)
Quick Recipes
Common effect combinations — complete rendering pipelines assembled from technique modules.
Photorealistic SDF Scene
- Geometry: sdf-3d (extended primitives) + csg-boolean-operations (cubic/quartic smin)
- Rendering: ray-marching + normal-estimation (tetrahedron method)
- Lighting: lighting-model (outdoor three-light model) + shadow-techniques (improved soft shadow) + ambient-occlusion
- Atmosphere: atmospheric-scattering (height-based fog with sun tint)
- Post: post-processing (ACES tone mapping) + anti-aliasing (2x SSAA) + camera-effects (vignette)
Organic / Biological Forms
- Geometry: sdf-3d (extended primitives + deformation operators: twist, bend) + csg-boolean (gradient-aware smin for material blending)
- Detail: procedural-noise (FBM with derivatives) + domain-warping
- Surface: lighting-model (subsurface scattering approximation via half-Lambert)
Procedural Landscape
- Terrain: terrain-rendering + procedural-noise (erosion FBM with derivatives)
- Texturing: texture-mapping-advanced (biplanar mapping + no-tile)
- Sky: atmospheric-scattering (Rayleigh/Mie + height fog)
- Water: water-ocean (Gerstner waves) + lighting-model (Fresnel reflections)
Stylized 2D Art
- Shapes: sdf-2d (extended library) + sdf-tricks (layered edges, hollowing)
- Color: color-palette (cosine palettes) + polar-uv-manipulation (kaleidoscope)
- Polish: anti-aliasing (SDF analytical AA) + post-processing (bloom, chromatic aberration)
Shader Debugging Techniques
Visual debugging methods — temporarily replace your output to diagnose issues.
| What to check |
Code |
What to look for |
| Surface normals |
col = nor * 0.5 + 0.5; |
Smooth gradients = correct normals; banding = epsilon too large |
| Ray march step count |
col = vec3(float(steps) / float(MAX_STEPS)); |
Red hotspots = performance bottleneck; uniform = wasted iterations |
| Depth / distance |
col = vec3(t / MAX_DIST); |
Verify correct hit distances |
| UV coordinates |
col = vec3(uv, 0.0); |
Check coordinate mapping |
| SDF distance field |
col = (d > 0.0 ? vec3(0.9,0.6,0.3) : vec3(0.4,0.7,0.85)) * (0.8 + 0.2*cos(150.0*d)); |
Visualize SDF bands and zero-crossing |
| Checker pattern (UV) |
col = vec3(mod(floor(uv.x*10.)+floor(uv.y*10.), 2.0)); |
Verify UV distortion, seams |
| Lighting only |
col = vec3(shadow); or col = vec3(ao); |
Isolate shadow/AO contributions |
| Material ID |
col = palette(matId / maxMatId); |
Verify material assignment |
Source: MiniMax-AI/skills → skills/shader-dev/SKILL.md
1---2name: shader-dev3description: Comprehensive GLSL shader techniques for creating stunning visual effects — ray marching, SDF modeling, fluid simulation, particle systems, procedural generation, lighting, post-processing, and more.4---5
6
7# Shader Craft
8
9A unified skill covering 36 GLSL shader techniques (ShaderToy-compatible) for real-time visual effects.
10
11## Invocation
12
13```
14/shader-dev <request>
15```
16
17`$ARGUMENTS` contains the user's request (e.g. "create a raymarched SDF scene with soft shadows").
18
19## Skill Structure
20
21```
22shader-dev/
23├── SKILL.md # Core skill (this file)
24├── techniques/ # Implementation guides (read per routing table)
25│ ├── ray-marching.md # Sphere tracing with SDF
26│ ├── sdf-3d.md # 3D signed distance functions
27│ ├── lighting-model.md # PBR, Phong, toon shading
28│ ├── procedural-noise.md # Perlin, Simplex, FBM
29│ └── ... # 34 more technique files
30└── reference/ # Detailed guides (read as needed)
31 ├── ray-marching.md # Math derivations & advanced patterns
32 ├── sdf-3d.md # Extended SDF theory
33 ├── lighting-model.md # Lighting math deep-dive
34 ├── procedural-noise.md # Noise function theory
35 └── ... # 34 more reference files
36```
37
38## How to Use
39
401. Read the **Technique Routing Table** below to identify which technique(s) match the user's request
412. Read the relevant file(s) from `techniques/` — each file contains core principles, implementation steps, and complete code templates
423. If you need deeper understanding (math derivations, advanced patterns), follow the reference link at the bottom of each technique file to `reference/`
434. Apply the **WebGL2 Adaptation Rules** below when generating standalone HTML pages
44
45## Technique Routing Table
46
47| User wants to create... | Primary technique | Combine with |
48|---|---|---|
49| 3D objects / scenes from math | [ray-marching](techniques/ray-marching.md) + [sdf-3d](techniques/sdf-3d.md) | lighting-model, shadow-techniques |
50| Complex 3D shapes (booleans, blends) | [csg-boolean-operations](techniques/csg-boolean-operations.md) | sdf-3d, ray-marching |
51| Infinite repeating patterns in 3D | [domain-repetition](techniques/domain-repetition.md) | sdf-3d, ray-marching |
52| Organic / warped shapes | [domain-warping](techniques/domain-warping.md) | procedural-noise |
53| Fluid / smoke / ink effects | [fluid-simulation](techniques/fluid-simulation.md) | multipass-buffer |
54| Particle effects (fire, sparks, snow) | [particle-system](techniques/particle-system.md) | procedural-noise, color-palette |
55| Physically-based simulations | [simulation-physics](techniques/simulation-physics.md) | multipass-buffer |
56| Game of Life / reaction-diffusion | [cellular-automata](techniques/cellular-automata.md) | multipass-buffer, color-palette |
57| Ocean / water surface | [water-ocean](techniques/water-ocean.md) | atmospheric-scattering, lighting-model |
58| Terrain / landscape | [terrain-rendering](techniques/terrain-rendering.md) | atmospheric-scattering, procedural-noise |
59| Clouds / fog / volumetric fire | [volumetric-rendering](techniques/volumetric-rendering.md) | procedural-noise, atmospheric-scattering |
60| Sky / sunset / atmosphere | [atmospheric-scattering](techniques/atmospheric-scattering.md) | volumetric-rendering |
61| Realistic lighting (PBR, Phong) | [lighting-model](techniques/lighting-model.md) | shadow-techniques, ambient-occlusion |
62| Shadows (soft / hard) | [shadow-techniques](techniques/shadow-techniques.md) | lighting-model |
63| Ambient occlusion | [ambient-occlusion](techniques/ambient-occlusion.md) | lighting-model, normal-estimation |
64| Path tracing / global illumination | [path-tracing-gi](techniques/path-tracing-gi.md) | analytic-ray-tracing, multipass-buffer |
65| Precise ray-geometry intersections | [analytic-ray-tracing](techniques/analytic-ray-tracing.md) | lighting-model |
66| Voxel worlds (Minecraft-style) | [voxel-rendering](techniques/voxel-rendering.md) | lighting-model, shadow-techniques |
67| Noise / FBM textures | [procedural-noise](techniques/procedural-noise.md) | domain-warping |
68| Tiled 2D patterns | [procedural-2d-pattern](techniques/procedural-2d-pattern.md) | polar-uv-manipulation |
69| Voronoi / cell patterns | [voronoi-cellular-noise](techniques/voronoi-cellular-noise.md) | color-palette |
70| Fractals (Mandelbrot, Julia, 3D) | [fractal-rendering](techniques/fractal-rendering.md) | color-palette, polar-uv-manipulation |
71| Color grading / palettes | [color-palette](techniques/color-palette.md) | — |
72| Bloom / tone mapping / glitch | [post-processing](techniques/post-processing.md) | multipass-buffer |
73| Multi-pass ping-pong buffers | [multipass-buffer](techniques/multipass-buffer.md) | — |
74| Texture / sampling techniques | [texture-sampling](techniques/texture-sampling.md) | — |
75| Camera / matrix transforms | [matrix-transform](techniques/matrix-transform.md) | — |
76| Surface normals | [normal-estimation](techniques/normal-estimation.md) | — |
77| Polar coords / kaleidoscope | [polar-uv-manipulation](techniques/polar-uv-manipulation.md) | procedural-2d-pattern |
78| 2D shapes / UI from SDF | [sdf-2d](techniques/sdf-2d.md) | color-palette |
79| Procedural audio / music | [sound-synthesis](techniques/sound-synthesis.md) | — |
80| SDF tricks / optimization | [sdf-tricks](techniques/sdf-tricks.md) | sdf-3d, ray-marching |
81| Anti-aliased rendering | [anti-aliasing](techniques/anti-aliasing.md) | sdf-2d, post-processing |
82| Depth of field / motion blur / lens effects | [camera-effects](techniques/camera-effects.md) | post-processing, multipass-buffer |
83| Advanced texture mapping / no-tile textures | [texture-mapping-advanced](techniques/texture-mapping-advanced.md) | terrain-rendering, texture-sampling |
84| WebGL2 shader errors / debugging | [webgl-pitfalls](techniques/webgl-pitfalls.md) | — |
85
86## Technique Index
87
88### Geometry & SDF
89- **sdf-2d** — 2D signed distance functions for shapes, UI, anti-aliased rendering
90- **sdf-3d** — 3D signed distance functions for real-time implicit surface modeling
91- **csg-boolean-operations** — Constructive solid geometry: union, subtraction, intersection with smooth blending
92- **domain-repetition** — Infinite space repetition, folding, and limited tiling
93- **domain-warping** — Distort domains with noise for organic, flowing shapes
94- **sdf-tricks** — SDF optimization, bounding volumes, binary search refinement, hollowing, layered edges, debug visualization
95
96### Ray Casting & Lighting
97- **ray-marching** — Sphere tracing with SDF for 3D scene rendering
98- **analytic-ray-tracing** — Closed-form ray-primitive intersections (sphere, plane, box, torus)
99- **path-tracing-gi** — Monte Carlo path tracing for photorealistic global illumination
100- **lighting-model** — Phong, Blinn-Phong, PBR (Cook-Torrance), and toon shading
101- **shadow-techniques** — Hard shadows, soft shadows (penumbra estimation), cascade shadows
102- **ambient-occlusion** — SDF-based AO, screen-space AO approximation
103- **normal-estimation** — Finite-difference normals, tetrahedron technique
104
105### Simulation & Physics
106- **fluid-simulation** — Navier-Stokes fluid solver with advection, diffusion, pressure projection
107- **simulation-physics** — GPU-based physics: springs, cloth, N-body gravity, collision
108- **particle-system** — Stateless and stateful particle systems (fire, rain, sparks, galaxies)
109- **cellular-automata** — Game of Life, reaction-diffusion (Turing patterns), sand simulation
110
111### Natural Phenomena
112- **water-ocean** — Gerstner waves, FFT ocean, caustics, underwater fog
113- **terrain-rendering** — Heightfield ray marching, FBM terrain, erosion
114- **atmospheric-scattering** — Rayleigh/Mie scattering, god rays, SSS approximation
115- **volumetric-rendering** — Volume ray marching for clouds, fog, fire, explosions
116
117### Procedural Generation
118- **procedural-noise** — Value noise, Perlin, Simplex, Worley, FBM, ridged noise
119- **procedural-2d-pattern** — Brick, hexagon, truchet, Islamic geometric patterns
120- **voronoi-cellular-noise** — Voronoi diagrams, Worley noise, cracked earth, crystal
121- **fractal-rendering** — Mandelbrot, Julia sets, 3D fractals (Mandelbox, Mandelbulb)
122- **color-palette** — Cosine palettes, HSL/HSV/Oklab, dynamic color mapping
123
124### Post-Processing & Infrastructure
125- **post-processing** — Bloom, tone mapping (ACES, Reinhard), vignette, chromatic aberration, glitch
126- **multipass-buffer** — Ping-pong FBO setup, state persistence across frames
127- **texture-sampling** — Bilinear, bicubic, mipmap, procedural texture lookup
128- **matrix-transform** — Camera look-at, projection, rotation, orbit controls
129- **polar-uv-manipulation** — Polar/log-polar coordinates, kaleidoscope, spiral mapping
130- **anti-aliasing** — SSAA, SDF analytical AA, temporal anti-aliasing (TAA), FXAA post-process
131- **camera-effects** — Depth of field (thin lens), motion blur, lens distortion, film grain, vignette
132- **texture-mapping-advanced** — Biplanar mapping, texture repetition avoidance, ray differential filtering
133
134### Audio
135- **sound-synthesis** — Procedural audio in GLSL: oscillators, envelopes, filters, FM synthesis
136
137### Debugging & Validation
138- **webgl-pitfalls** — Common WebGL2/GLSL errors: `fragCoord`, `main()` wrapper, function order, macro limitations, uniform null
139
140## WebGL2 Adaptation Rules
141
142All technique files use ShaderToy GLSL style. When generating standalone HTML pages, apply these adaptations:
143
144### Shader Version & Output
145- Use `canvas.getContext("webgl2")`
146- Shader first line: `#version 300 es`, fragment shader adds `precision highp float;`
147- Fragment shader must declare: `out vec4 fragColor;`
148- Vertex shader: `attribute` → `in`, `varying` → `out`
149- Fragment shader: `varying` → `in`, `gl_FragColor` → `fragColor`, `texture2D()` → `texture()`
150
151### Fragment Coordinate
152- **Use `gl_FragCoord.xy`** instead of `fragCoord` (WebGL2 does not have `fragCoord` built-in)
153```glsl
154// WRONG
155vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.y;
156// CORRECT
157vec2 uv = (2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.y;
158```
159
160### main() Wrapper for ShaderToy Templates
161- ShaderToy uses `void mainImage(out vec4 fragColor, in vec2 fragCoord)`
162- WebGL2 requires standard `void main()` entry point — always wrap mainImage:
163```glsl
164void mainImage(out vec4 fragColor, in vec2 fragCoord) {
165 // shader code...
166 fragColor = vec4(col, 1.0);
167}
168
169void main() {
170 mainImage(fragColor, gl_FragCoord.xy);
171}
172```
173
174### Function Declaration Order
175- GLSL requires functions to be declared before use — either declare before use or reorder:
176```glsl
177// WRONG — getAtmosphere() calls getSunDirection() before it's defined
178vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Error!
179vec3 getSunDirection() { return normalize(vec3(1.0)); }
180
181// CORRECT — define callee first
182vec3 getSunDirection() { return normalize(vec3(1.0)); }
183vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Works
184```
185
186### Macro Limitations
187- `#define` cannot use function calls — use `const` instead:
188```glsl
189// WRONG
190#define SUN_DIR normalize(vec3(0.8, 0.4, -0.6))
191
192// CORRECT
193const vec3 SUN_DIR = vec3(0.756, 0.378, -0.567); // Pre-computed normalized value
194```
195
196### Script Tag Extraction
197- When extracting shader source from `<script>` tags, ensure `#version` is the **first character** — use `.trim()`:
198```javascript
199const fs = document.getElementById('fs').text.trim();
200```
201
202### Common Pitfalls
203- **Unused uniforms**: Compiler may optimize away unused uniforms, causing `gl.getUniformLocation()` to return `null` — always use uniforms in a way the compiler cannot optimize out
204- **Loop indices**: Use runtime constants in loops, not `#define` macros in some ES versions
205- **Terrain functions**: Functions like `terrainM(vec2)` need XZ components — use `terrainM(pos.xz + offset)` not `terrainM(pos + offset)`
206
207## HTML Page Setup
208
209When generating a standalone HTML page:
210
211- Canvas fills the entire viewport, auto-resizes on window resize
212- Page background black, no scrollbars: `body { margin: 0; overflow: hidden; background: #000; }`
213- Implement ShaderToy-compatible uniforms: `iTime`, `iResolution`, `iMouse`, `iFrame`
214- For multi-pass effects (Buffer A/B), use WebGL2 framebuffer + ping-pong (see multipass-buffer technique)
215
216## Common Pitfalls
217
218### JS Variable Declaration Order (TDZ — causes white screen crash)
219
220`let`/`const` variables must be declared at the **top** of the `<script>` block, before any function that references them:
221
222```javascript
223// 1. State variables FIRST
224let frameCount = 0;
225let startTime = Date.now();
226
227// 2. Canvas/GL init, shader compile, FBO creation
228const canvas = document.getElementById('canvas');
229const gl = canvas.getContext('webgl2');
230// ...
231
232// 3. Functions and event bindings LAST
233function resize() { /* can now safely reference frameCount */ }
234function render() { /* ... */ }
235window.addEventListener('resize', resize);
236```
237
238Reason: `let`/`const` have a Temporal Dead Zone — referencing them before declaration throws `ReferenceError`, causing a white screen.
239
240### GLSL Compilation Errors (self-check after writing shaders)
241
242- **Function signature mismatch**: Call must exactly match definition in parameter count and types. If defined as `float fbm(vec3 p)`, cannot call `fbm(uv)` with a `vec2`
243- **Reserved words as variable names**: Do not use: `patch`, `cast`, `sample`, `filter`, `input`, `output`, `common`, `partition`, `active`
244- **Strict type matching**: `vec3 x = 1.0` is illegal — use `vec3 x = vec3(1.0)`; cannot use `.z` to access a `vec2`
245- **No ternary on structs**: ESSL does not allow ternary operator on struct types — use `if`/`else` instead
246
247### Performance Budget
248
249Deployment environments may use headless software rendering with limited GPU power. Stay within these limits:
250
251- Ray marching main loop: ≤ 128 steps
252- Volume sampling / lighting inner loops: ≤ 32 steps
253- FBM octaves: ≤ 6 layers
254- Total nested loop iterations per pixel: ≤ 1000 (exceeding this freezes the browser)
255
256## Quick Recipes
257
258Common effect combinations — complete rendering pipelines assembled from technique modules.
259
260### Photorealistic SDF Scene
2611. **Geometry**: sdf-3d (extended primitives) + csg-boolean-operations (cubic/quartic smin)
2622. **Rendering**: ray-marching + normal-estimation (tetrahedron method)
2633. **Lighting**: lighting-model (outdoor three-light model) + shadow-techniques (improved soft shadow) + ambient-occlusion
2644. **Atmosphere**: atmospheric-scattering (height-based fog with sun tint)
2655. **Post**: post-processing (ACES tone mapping) + anti-aliasing (2x SSAA) + camera-effects (vignette)
266
267### Organic / Biological Forms
2681. **Geometry**: sdf-3d (extended primitives + deformation operators: twist, bend) + csg-boolean (gradient-aware smin for material blending)
2692. **Detail**: procedural-noise (FBM with derivatives) + domain-warping
2703. **Surface**: lighting-model (subsurface scattering approximation via half-Lambert)
271
272### Procedural Landscape
2731. **Terrain**: terrain-rendering + procedural-noise (erosion FBM with derivatives)
2742. **Texturing**: texture-mapping-advanced (biplanar mapping + no-tile)
2753. **Sky**: atmospheric-scattering (Rayleigh/Mie + height fog)
2764. **Water**: water-ocean (Gerstner waves) + lighting-model (Fresnel reflections)
277
278### Stylized 2D Art
2791. **Shapes**: sdf-2d (extended library) + sdf-tricks (layered edges, hollowing)
2802. **Color**: color-palette (cosine palettes) + polar-uv-manipulation (kaleidoscope)
2813. **Polish**: anti-aliasing (SDF analytical AA) + post-processing (bloom, chromatic aberration)
282
283## Shader Debugging Techniques
284
285Visual debugging methods — temporarily replace your output to diagnose issues.
286
287| What to check | Code | What to look for |
288|---|---|---|
289| Surface normals | `col = nor * 0.5 + 0.5;` | Smooth gradients = correct normals; banding = epsilon too large |
290| Ray march step count | `col = vec3(float(steps) / float(MAX_STEPS));` | Red hotspots = performance bottleneck; uniform = wasted iterations |
291| Depth / distance | `col = vec3(t / MAX_DIST);` | Verify correct hit distances |
292| UV coordinates | `col = vec3(uv, 0.0);` | Check coordinate mapping |
293| SDF distance field | `col = (d > 0.0 ? vec3(0.9,0.6,0.3) : vec3(0.4,0.7,0.85)) * (0.8 + 0.2*cos(150.0*d));` | Visualize SDF bands and zero-crossing |
294| Checker pattern (UV) | `col = vec3(mod(floor(uv.x*10.)+floor(uv.y*10.), 2.0));` | Verify UV distortion, seams |
295| Lighting only | `col = vec3(shadow);` or `col = vec3(ao);` | Isolate shadow/AO contributions |
296| Material ID | `col = palette(matId / maxMatId);` | Verify material assignment |
297
298---
299
300**Source:** [`MiniMax-AI/skills`](https://github.com/MiniMax-AI/skills) → `skills/shader-dev/SKILL.md`