A unified skill covering 36 GLSL shader techniques (ShaderToy-compatible) for real-time visual effects.
text
/shader-dev <request>
$ARGUMENTS contains the user's request (e.g. "create a raymarched SDF scene with soft shadows").
text
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
techniques/ — each file contains core principles, implementation steps, and complete code templatesreference/User wants to create...Primary techniqueCombine with3D objects / scenes from mathray-marching + sdf-3dlighting-model, shadow-techniquesComplex 3D shapes (booleans, blends)csg-boolean-operationssdf-3d, ray-marchingInfinite repeating patterns in 3Ddomain-repetitionsdf-3d, ray-marchingOrganic / warped shapesdomain-warpingprocedural-noiseFluid / smoke / ink effectsfluid-simulationmultipass-bufferParticle effects (fire, sparks, snow)particle-systemprocedural-noise, color-palettePhysically-based simulationssimulation-physicsmultipass-bufferGame of Life / reaction-diffusioncellular-automatamultipass-buffer, color-paletteOcean / water surfacewater-oceanatmospheric-scattering, lighting-modelTerrain / landscapeterrain-renderingatmospheric-scattering, procedural-noiseClouds / fog / volumetric firevolumetric-renderingprocedural-noise, atmospheric-scatteringSky / sunset / atmosphereatmospheric-scatteringvolumetric-renderingRealistic lighting (PBR, Phong)lighting-modelshadow-techniques, ambient-occlusionShadows (soft / hard)shadow-techniqueslighting-modelAmbient occlusionambient-occlusionlighting-model, normal-estimationPath tracing / global illuminationpath-tracing-gianalytic-ray-tracing, multipass-bufferPrecise ray-geometry intersectionsanalytic-ray-tracinglighting-modelVoxel worlds (Minecraft-style)voxel-renderinglighting-model, shadow-techniquesNoise / FBM texturesprocedural-noisedomain-warpingTiled 2D patternsprocedural-2d-patternpolar-uv-manipulationVoronoi / cell patternsvoronoi-cellular-noisecolor-paletteFractals (Mandelbrot, Julia, 3D)fractal-renderingcolor-palette, polar-uv-manipulationColor grading / palettescolor-palette—Bloom / tone mapping / glitchpost-processingmultipass-bufferMulti-pass ping-pong buffersmultipass-buffer—Texture / sampling techniquestexture-sampling—Camera / matrix transformsmatrix-transform—Surface normalsnormal-estimation—Polar coords / kaleidoscopepolar-uv-manipulationprocedural-2d-pattern2D shapes / UI from SDFsdf-2dcolor-paletteProcedural audio / musicsound-synthesis—SDF tricks / optimizationsdf-trickssdf-3d, ray-marchingAnti-aliased renderinganti-aliasingsdf-2d, post-processingDepth of field / motion blur / lens effectscamera-effectspost-processing, multipass-bufferAdvanced texture mapping / no-tile texturestexture-mapping-advancedterrain-rendering, texture-samplingWebGL2 shader errors / debuggingwebgl-pitfalls—
fragCoord, main() wrapper, function order, macro limitations, uniform nullAll technique files use ShaderToy GLSL style. When generating standalone HTML pages, apply these adaptations:
canvas.getContext("webgl2")#version 300 es, fragment shader adds precision highp float;out vec4 fragColor;attribute → in, varying → outvarying → in, gl_FragColor → fragColor, texture2D() → texture()gl_FragCoord.xy instead of fragCoord (WebGL2 does not have fragCoord built-in)glsl
// WRONG
vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.y;
// CORRECT
vec2 uv = (2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.y;
void mainImage(out vec4 fragColor, in vec2 fragCoord)void main() entry point — always wrap mainImage:glsl
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// shader code...
fragColor = vec4(col, 1.0);
}
void main() {
mainImage(fragColor, gl_FragCoord.xy);
}
glsl
// 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
#define cannot use function calls — use const instead:glsl
// 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> tags, ensure #version is the first character — use .trim():javascript
const fs = document.getElementById('fs').text.trim();
gl.getUniformLocation() to return null — always use uniforms in a way the compiler cannot optimize out#define macros in some ES versionsterrainM(vec2) need XZ components — use terrainM(pos.xz + offset) not terrainM(pos + offset)When generating a standalone HTML page:
body { margin: 0; overflow: hidden; background: #000; }iTime, iResolution, iMouse, iFramelet/ const variables must be declared at the top of the <script> block, before any function that references them:
javascript
// 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.
float fbm(vec3 p), cannot call fbm(uv) with a vec2patch, cast, sample, filter, input, output, common, partition, activevec3 x = 1.0 is illegal — use vec3 x = vec3(1.0); cannot use .z to access a vec2if/ else insteadDeployment environments may use headless software rendering with limited GPU power. Stay within these limits:
Common effect combinations — complete rendering pipelines assembled from technique modules.
Visual debugging methods — temporarily replace your output to diagnose issues.
What to checkCodeWhat to look forSurface normalscol = nor * 0.5 + 0.5;Smooth gradients = correct normals; banding = epsilon too largeRay march step countcol = vec3(float(steps) / float(MAX_STEPS));Red hotspots = performance bottleneck; uniform = wasted iterationsDepth / distancecol = vec3(t / MAX_DIST);Verify correct hit distancesUV coordinatescol = vec3(uv, 0.0);Check coordinate mappingSDF distance fieldcol = (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-crossingChecker pattern (UV)col = vec3(mod(floor(uv.x*10.)+floor(uv.y*10.), 2.0));Verify UV distortion, seamsLighting onlycol = vec3(shadow); or col = vec3(ao);Isolate shadow/AO contributionsMaterial IDcol = palette(matId / maxMatId);Verify material assignment