Marketplace shader-programming-glsl
Expert guide for writing efficient GLSL shaders (Vertex/Fragment) for web and game engines, covering syntax, uniforms, and common effects.
install
source · Clone the upstream repo
git clone https://github.com/aiskillstore/marketplace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/sickn33/shader-programming-glsl" ~/.claude/skills/aiskillstore-marketplace-shader-programming-glsl && rm -rf "$T"
manifest:
skills/sickn33/shader-programming-glsl/SKILL.mdsource content
Shader Programming GLSL
Overview
A comprehensive guide to writing GPU shaders using GLSL (OpenGL Shading Language). Learn syntax, uniforms, varying variables, and key mathematical concepts like swizzling and vector operations for visual effects.
When to Use This Skill
- Use when creating custom visual effects in WebGL, Three.js, or game engines.
- Use when optimizing graphics rendering performance.
- Use when implementing post-processing effects (blur, bloom, color correction).
- Use when procedurally generating textures or geometry on the GPU.
Step-by-Step Guide
1. Structure: Vertex vs. Fragment
Understand the pipeline:
- Vertex Shader: Transforms 3D coordinates to 2D screen space (
).gl_Position - Fragment Shader: Colors individual pixels (
).gl_FragColor
// Vertex Shader (basic) attribute vec3 position; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
// Fragment Shader (basic) uniform vec3 color; void main() { gl_FragColor = vec4(color, 1.0); }
2. Uniforms and Varyings
: Data constant for all vertices/fragments (passed from CPU).uniform
: Data interpolated from vertex to fragment shader.varying
// Passing UV coordinates varying vec2 vUv; // In Vertex Shader void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } // In Fragment Shader void main() { // Gradient based on UV gl_FragColor = vec4(vUv.x, vUv.y, 1.0, 1.0); }
3. Swizzling & Vector Math
Access vector components freely:
vec4 color = vec4(1.0, 0.5, 0.0, 1.0);
->color.rgbvec3(1.0, 0.5, 0.0)
->color.zyx
(reordering)vec3(0.0, 0.5, 1.0)
Examples
Example 1: Simple Raymarching (SDF Sphere)
float sdSphere(vec3 p, float s) { return length(p) - s; } void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y; vec3 ro = vec3(0.0, 0.0, -3.0); // Ray Origin vec3 rd = normalize(vec3(uv, 1.0)); // Ray Direction float t = 0.0; for(int i = 0; i < 64; i++) { vec3 p = ro + rd * t; float d = sdSphere(p, 1.0); // Sphere radius 1.0 if(d < 0.001) break; t += d; } vec3 col = vec3(0.0); if(t < 10.0) { vec3 p = ro + rd * t; vec3 normal = normalize(p); col = normal * 0.5 + 0.5; // Color by normal } fragColor = vec4(col, 1.0); }
Best Practices
- ✅ Do: Use
for linear interpolation instead of manual math.mix() - ✅ Do: Use
andstep()
for thresholding and soft edges (avoidsmoothstep()
branches).if - ✅ Do: Pack data into vectors (
) to minimize memory access.vec4 - ❌ Don't: Use heavy branching (
) inside loops if possible; it hurts GPU parallelism.if-else - ❌ Don't: Calculate constant values inside the shader; pre-calculate them on the CPU (uniforms).
Troubleshooting
Problem: Shader compiles but screen is black. Solution: Check if
gl_Position.w is correct (usually 1.0). Check if uniforms are actually being set from the host application. Verify UV coordinates are within [0, 1].