
Shadertoy
Copy battle-tested GLSL UV setup and complex-number helpers when authoring Shadertoy-style fragment shaders.
Overview
Shadertoy is an agent skill for the Build phase that supplies reusable GLSL coordinate and complex-number patterns for Shadertoy-style fragment shaders.
Install
npx skills add https://github.com/bfollington/terma --skill shadertoyWhat is this skill?
- Documents aspect-correct UV normalization centered at origin
- Provides simple 0–1 UV and centered-effect coordinate variants
- Defines complex multiply, divide, sin, cos, tan, log, and polar helpers as GLSL macros
- Extracted from real shader work for Shadertoy-style pipelines
- Focuses on reusable idioms rather than a single finished effect
Adoption & trust: 1.4k installs on skills.sh; 47 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are writing a shader and keep re-deriving UV normalization and complex math helpers incorrectly across Shadertoy or WebGL projects.
Who is it for?
Indie creatives and solo devs building generative visuals, demoscene-style effects, or shader-driven game backgrounds.
Skip if: Teams needing a full rendering engine, material pipeline, or non-GLSL graphics APIs without fragment shaders.
When should I use this skill?
Authoring or refactoring Shadertoy-style GLSL and need standard UV or complex-number patterns.
What do I get? / Deliverables
You paste vetted GLSL snippets for UV spaces and complex operations so you can focus on the creative effect instead of coordinate bugs.
- Reusable GLSL coordinate setup blocks
- Complex math helper macros and functions
- Effect-ready mathematical scaffolding
Recommended Skills
Journey fit
Build is the primary shelf because the skill supplies implementation patterns while writing shader code, not distribution or ops. Frontend subphase fits fragment-shader UI/visual output even when the product is a game or generative art demo.
How it compares
Use as a GLSL pattern cookbook, not a substitute for Shadertoy’s live editor or a game engine material graph.
Common Questions / FAQ
Who is shadertoy for?
Solo builders authoring fragment shaders who want documented UV and complex-math snippets compatible with Shadertoy conventions.
When should I use shadertoy?
Use it during Build while implementing shader effects—especially when setting up fragCoord UV math or complex-domain coloring before tuning the visual idea.
Is shadertoy safe to install?
It is reference documentation without mandatory shell or network calls; review the Security Audits panel on this Prism page like any third-party skill.
SKILL.md
READMESKILL.md - Shadertoy
# Common Shadertoy Patterns and Techniques This document contains reusable patterns, techniques, and best practices extracted from real shader work. ## Coordinate System Setup ### Standard UV Normalization (Aspect-Corrected) ```glsl // Centers coordinates at (0,0) with aspect ratio correction vec2 uv = (fragCoord.xy - 0.5 * iResolution.xy) / min(iResolution.y, iResolution.x); // OR alternative form: vec2 uv = (fragCoord * 2.0 - iResolution.xy) / min(iResolution.x, iResolution.y); ``` ### Simple Normalized UV (0 to 1) ```glsl vec2 uv = fragCoord / iResolution.xy; ``` ### Centered UV for Effects ```glsl vec2 uv = fragCoord / iResolution.xy - vec2(1.0, 0.5); ``` ## Complex Number Mathematics ### Complex Number Operations ```glsl // Complex multiplication #define cx_mul(a, b) vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x) // Complex division #define cx_div(a, b) vec2(((a.x*b.x + a.y*b.y)/(b.x*b.x + b.y*b.y)),((a.y*b.x - a.x*b.y)/(b.x*b.x + b.y*b.y))) // Complex sine #define cx_sin(a) vec2(sin(a.x) * cosh(a.y), cos(a.x) * sinh(a.y)) // Complex cosine #define cx_cos(a) vec2(cos(a.x) * cosh(a.y), -sin(a.x) * sinh(a.y)) // Complex tangent vec2 cx_tan(vec2 a) { return cx_div(cx_sin(a), cx_cos(a)); } // Complex logarithm vec2 cx_log(vec2 a) { float rpart = sqrt((a.x * a.x) + (a.y * a.y)); float ipart = atan(a.y, a.x); if (ipart > PI) ipart = ipart - (2.0 * PI); return vec2(log(rpart), ipart); } // Convert to polar coordinates vec2 as_polar(vec2 z) { return vec2(length(z), atan(z.y, z.x)); } // Complex power vec2 cx_pow(vec2 v, float p) { vec2 z = as_polar(v); return pow(z.x, p) * vec2(cos(z.y * p), sin(z.y * p)); } ``` ## Color Palettes ### Cosine Palette (IQ's Famous Technique) ```glsl vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) { return a + b * cos(2.0 * PI * (c * t + d)); } // Example presets: vec3 chrome(float t) { return palette(t, vec3(0.5, 0.5, 0.5), // base vec3(0.5, 0.5, 0.5), // amplitude vec3(1.0, 1.0, 0.5), // frequency vec3(0.8, 0.90, 0.30) // phase ); } ``` ### Multi-Layer Palettes with Noise ```glsl vec3 palette(float t, int layer) { vec3[3] a = vec3[]( vec3(0.01, 0.012, 0.015), vec3(0.012, 0.01, 0.015), vec3(0.01, 0.013, 0.015) ); vec3[3] b = vec3[]( vec3(0.03, 0.03, 0.04), vec3(0.035, 0.025, 0.04), vec3(0.025, 0.035, 0.04) ); float noise = hash21(vec2(t, float(layer))) * 0.01; return a[layer] + b[layer] * (0.5 + 0.5 * sin(t * PI * 2.0)) + noise; } ``` ## Hash Functions (Pseudo-Random) ### Simple 2D Hash ```glsl float hash21(vec2 p) { p = fract(p * vec2(234.34, 435.345)); p += dot(p, p + 34.23); return fract(p.x * p.y); } ``` ### PCG Hash (High Quality) ```glsl uint pcg_hash(uint seed) { uint state = seed * 747796405u + 2891336453u; uint word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u; return (word >> 22u) ^ word; } ``` ## Ray Marching ### Basic Ray Marching Loop ```glsl vec3 render(vec3 ro, vec3 rd, float timeOffset) { float t = 0.0; float maxd = 10.0; vec3 col = vec3(0.0); for (int i = 0; i < 100; i++) { vec3 p = ro + rd * t; float d = map(p, timeOffset); if (d < 0.001) { // Hit surface - compute lighting vec3 n = calcNormal(p, timeOffset); // ... lighting calculations break; } if (t > maxd) break; t += d * 0.5; // Step multiplier (0.5 for safety) } return col; } ``` ### Normal Calculation (Tetrahedron Method) ```glsl vec3 calcNormal(vec3 p, float timeOffset) { vec2 e = vec2(0.001, 0.0); return normalize(vec3( map(p + e.xyy, timeOffset) - map(p - e.xyy, timeOffset), map(p + e.yxy, timeOffset) - map(p - e.yxy, timeOffset), map(p + e.yyx, timeOffset) - map(p - e.yyx, timeOffset) )); } ``` ## 3D Transformations ### Axis-Angle Rotation ``