ai-behavior-trees-util…
Engine-neutral behavior tree and utility AI code for NPCs in any language: Blackboard, reactive composites, decorators and…
Engine-neutral shader technique in GLSL with HLSL equivalents: how dissolve, outline, fresnel rim and post effects work, and porting GLSL to HLSL. Use when the math of an effect is the question, or for specks or mobile shimmer. To write a shader in one engine, its skill alone is
Claude Code
$ npx -y skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming --agent claude-code
Codex
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a codex -y
Cursor
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a cursor -y
Gemini CLI
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a gemini-cli -y
GitHub Copilot
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a github-copilot -y
OpenCode
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a opencode -y
Windsurf
$ npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill shader-programming -a windsurf -y
name: shader-programming description: > Engine-neutral shader technique in GLSL with HLSL equivalents: how dissolve, outline, fresnel rim and post effects work, and porting GLSL to HLSL. Use when the math of an effect is the question, or for specks or mobile shimmer. To write a shader in one engine, its skill alone is enough (`godot-shaders`, `threejs-materials-lighting`, `pixijs-rendering`). Not for particles (`unreal-niagara`).
Shaders run per vertex and per pixel on the GPU. The pipeline, coordinate spaces, UV tricks and the maths behind common effects port across engines; only the dialect and built-in names change. This skill owns that technique in GLSL with HLSL equivalents. Load the engine skill (`godot-shaders`, `threejs-materials-lighting`, `pixijs-rendering`) as well for the syntax, built-ins and how the material is wired.
grading.
**Not this skill:** Godot shading language syntax and pipeline (`godot-shaders`), three.js `ShaderMaterial` vs TSL (`threejs-materials-lighting`), PixiJS filters (`pixijs-rendering`), particle systems (`unreal-niagara`), post-process stack settings (the engine's renderer docs), per-pixel cost in a profiler (`performance-optimization`).
1. **Name the stage.** The vertex stage moves vertices to clip space and passes data on; the fragment stage runs per pixel and outputs a colour. Most game effects are fragment work. 2. **Pick one space** for lighting maths (world or view) and convert every vector into it. 3. **Drive effects with UVs, uniforms and time.** UVs are 0..1; uniforms are constant per draw; varyings are interpolated from vertex to fragment. 4. **Prefer `mix`, `step`, `smoothstep` and `clamp` to branches** on per-pixel values: pixels run in lockstep, so a branch that differs between neighbours runs both sides. A branch on a uniform is cheap. 5. **Keep texture samples few**; they are usually the main cost. 6. **Compile before looking** (see "Check it"). 7. **Ask for a visual check on the target device** with specific questions.
GLSL fragment snippets for desktop `#version 330`; each compiles with `glslangValidator` under that header. For GLSL ES 3.00 (WebGL 2, three.js `ShaderMaterial`, PixiJS filters) add `precision highp float;` and set uniform defaults from code: ES rejects `uniform float edge = 0.05;` with "cannot initialize this type of qualifier", while Godot's shading language accepts it. HLSL forms and the longer effects are in `references/effects.md`.
uniform sampler2D tex;
uniform vec4 tint; // multiply tints without clipping; (1,1,1,1) is unchanged
in vec2 uv;
out vec4 frag;
void main() {
vec4 c = texture(tex, uv); // HLSL: tex.Sample(samp, uv)
frag = c * tint;
}uniform sampler2D tex;
uniform float time; // seconds since start, supplied by the engine
uniform vec2 scroll_speed; // UV units per second
in vec2 uv;
out vec4 frag;
void main() {
vec2 scrolled = fract(uv + scroll_speed * time); // HLSL: frac(...)
frag = texture(tex, scrolled);
}
// Drive with an absolute time uniform, not a per-frame accumulator. With mipmaps, fract()
// leaves a thin seam where the UV jumps from 1 to 0; prefer a repeat sampler and drop fract().// Hide pixels where noise < threshold; tint a thin band at the boundary.
uniform sampler2D tex;
uniform sampler2D noise_tex; // grayscale noise, 0..1
uniform float amount; // 0 = fully visible, 1 = fully dissolved
uniform float edge = 0.05; // width of the glowing edge band
uniform vec4 edge_color;
in vec2 uv;
out vec4 frag;
void main() {
vec4 c = texture(tex, uv);
float n = texture(noise_tex, uv).r;
float cut = amount * (1.0 + edge) - edge; // edge band starts below 0 -> none at amount 0
if (n <= cut) discard; // cut away dissolved pixels (all of them at 1)
float e = smoothstep(cut, cut + edge, n); // 0 at the edge -> 1 inside; keep edge > 0
frag = mix(edge_color, c, e); // HLSL: lerp(edge_color, c, e)
}
// WRONG: thresholding at `amount` directly — at amount 0 every pixel with
// n < edge is still tinted, so the "fully visible" sprite shows glowing specks.in vec3 world_normal; // world space, interpolated from the vertex stage
in vec3 view_dir; // surface -> camera, world space
uniform float power = 3.0;
uniform vec3 rim_color;
out vec4 frag;
void main() {
// Interpolation does not preserve unit length, even with normalized vertex outputs.
vec3 normal = normalize(world_normal);
vec3 view = normalize(view_dir);
float f = pow(1.0 - clamp(dot(normal, view), 0.0, 1.0), power);
frag = vec4(rim_color * f, 1.0); // add to lighting; f peaks at the silhouette
}1. **Compile every GLSL file** with `glslangValidator path/to/effect.frag` (the stage comes from the suffix: `.vert`, `.frag`). Compile the ES variant too when it ships to the web: put `#version 300 es` and `precision highp float;` at the top. For WGSL run `naga path/to/shader.wgsl`. For Godot `.gdshader` files use the headless compile check in `godot-shaders`. 2. **Check the endpoints numerically** where the effect has parameters: dissolve at `amount` 0 shows no edge colour and at 1 discards everything; a vignette at `strength` 0 leaves the image unchanged. Read the maths off the code, or render a test quad in the engine and read pixels back. 3. **Ask the user to look on the target hardware** and report specific things: "Does the dissolve show specks a
<img src="docs/assets/awesome-gamedev-agent-skills-banner.png" width="820" alt="awesome-gamedev-agent-skills — game-dev skills for AI coding agents.
Engine-neutral behavior tree and utility AI code for NPCs in any language: Blackboard, reactive composites, decorators and…
Engine-neutral game audio technique: bus layout, volume sliders in decibels, loudness, ducking music under dialogue, adaptive…
Builds and tunes game cameras, engine-neutral with Godot and Cinemachine 3 mappings: 2D follow with deadzone and look-ahead,…
Plans, generates or sources, and validates consistent game art: style guides, sprites, pixel art, tilesets, icons and textures,…
Builds engine-neutral branching dialogue with Ink, Yarn Spinner or a small JSON graph runner: lines, choices, conditions,…
Designs engine-neutral enemy and NPC AI: picks FSM, behavior tree, utility or GOAP, and builds perception, steering and A*…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.