shader-dev

Comprehensive GLSL shader techniques for creating stunning visual effects — ray marching, SDF modeling, fluid simulation, particle systems, procedural…

INSTALLATION
npx skills add https://github.com/minimax-ai/skills --skill shader-dev
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

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 &#x26; 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 &#x26; 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 &#x26; 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 &#x26; 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 &#x26; 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 &#x26; 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 &#x26; 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: attributein, varyingout
  • Fragment shader: varyingin, gl_FragColorfragColor, 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

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card