godot-shaders — Claude Code skill: Godot 4.7 shaders
A skill that teaches your agent to write canvas_item and spatial shaders in the Godot Shading Language, with TIME animation, uniforms and screen reading. For 2D and 3D effects in Godot 4.7.
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a claude-codeWhat godot-shaders does
The skill sets the order of work for shaders in Godot 4.7. First line picks the type: shader_type canvas_item; for sprites and anything CanvasItem, or shader_type spatial; for 3D materials. Then a ShaderMaterial on the node, a fragment() writing to COLOR or ALBEDO, and uniforms with hints so the values show up in the Inspector.
Four worked patterns come with it: tint plus UV scroll driven by TIME, a dissolve against a NoiseTexture2D threshold, emissive rim light from NORMAL and VIEW, and a screen blur. Each is a real .gdshader, and there is a GDScript call for driving a uniform: material.set_shader_parameter("amount", 0.7).
A separate section covers the 3.x port. SCREEN_TEXTURE is gone, hint_color and hint_albedo became source_color. This is the one that bites: writing COLOR in a spatial shader changes nothing on screen. A color uniform without source_color skips the sRGB conversion and looks washed out. Also worth knowing before you chase a jumping effect: TIME wraps every time_rollover_secs, 3600 by default, so pick periods that divide it or feed your own time through a uniform.
What it helps with
- write a noise-threshold dissolve without hand-tuning
discard - build a 2D effect that scrolls its texture over time
- add emissive rim light to a 3D material
- blur the screen through
hint_screen_texture - move a Godot 3.x shader to 4.7 with the renamed hints
Example prompts for the agent
- Write
dissolve.gdshaderfor a Sprite2D: dissolve against aNoiseTexture2D, expose the threshold as a uniform withhint_range - Make a
spatialshader with rim light, put colour and strength into uniforms withsource_colorandhint_range - Port this shader from
SCREEN_TEXTUREtohint_screen_texturefor Godot 4.7
How to install godot-shaders
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a claude-code2Manually: put the files in place
~/.claude/skills/godot-shaders/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/godot-shaders/
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a codex2Manually: put the files in place
.agents/skills/godot-shaders/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a cursor2Manually: put the files in place
.cursor/skills/godot-shaders/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install gamedev-skills/awesome-gamedev-agent-skills godot-shaders2Manually: put the files in place
.github/skills/godot-shaders/SKILL.md1Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a gemini-cli2Platform CLI
gemini skills install https://github.com/gamedev-skills/awesome-gamedev-agent-skills --path skills/godot/godot-shadersManually: put the files in place
.devin/skills/godot-shaders/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about godot-shaders
How do I install godot-shaders in Claude Code?
Run npx skills add gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders -a claude-code. The skill lands in ~/.claude/skills/godot-shaders/SKILL.md.
What does godot-shaders do?
It guides the agent through writing and editing .gdshader files for Godot 4.7: shader type, fragment() and vertex(), uniforms with hints, TIME and UV animation, screen reading. It ships 2D and 3D patterns plus a list of common mistakes.
Does it work for 2D and 3D shaders?
Yes. canvas_item covers Sprite2D, TextureRect and other CanvasItem nodes, while spatial is for 3D materials. Each type has its own output variables, so the skill lists which one to write.
Source text
SKILL.md · Apache-2.0
---
name: godot-shaders
description: >
Write Godot 4.7 shaders in the Godot Shading Language: canvas_item shaders for 2D
and spatial shaders for 3D, with vertex/fragment functions, uniforms (source_color,
hint_range), TIME/UV animation, and screen-reading via hint_screen_texture. Use
when authoring .gdshader files, writing fragment/vertex code, making 2D/3D visual
effects, or porting 3.x shaders (SCREEN_TEXTURE, hint_color) to 4.x.
---
# Godot Shaders (4.x)
Write `canvas_item` (2D) and `spatial` (3D) shaders in the Godot Shading Language, animate
with `TIME`/`UV`, expose `uniform`s, and read the screen. Targets **Godot 4.7**.
## When to use
- Use when writing `.gdshader` code or a `ShaderMaterial`: 2D effects (outline, dissolve,
flash, water), 3D surface shaders (rim light, toon, scrolling UV), or screen-space
post effects.
**When *not* to use:** the cross-engine *concepts* of shading (UVs, vertex/fragment
theory) → `shader-programming`; particles/VFX nodes → general 3D; non-shader visuals.
## Core workflow
1. **Pick the shader type** on the first line: `shader_type canvas_item;` for 2D
(Sprite2D, TextureRect, anything `CanvasItem`) or `shader_type spatial;` for 3D
materials. (`particles`, `sky`, `fog` also exist.)
2. **Attach via a `ShaderMaterial`.** Create a `ShaderMaterial`, assign your `.gdshader`,
and put it on the node's `material`. Uniforms appear in the Inspector.
3. **Write `fragment()`** to set the output: `COLOR` (2D) or `ALBEDO`/`EMISSION`/`ALPHA`
(3D). Optionally `vertex()` to move geometry and `light()` for custom lighting.
4. **Expose tunables as `uniform`s** with hints (`source_color`, `hint_range`) so they are
editable and correctly color-managed.
5. **Animate with the built-in `TIME`** and sample textures with `texture(tex, UV)`.
6. **Set uniforms from code** with `material.set_shader_parameter("name", value)`.
## Patterns
### 1. 2D (canvas_item): tint + scrolling UV
```glsl
shader_type canvas_item;
uniform vec4 tint : source_color = vec4(1.0); // source_color = sRGB-correct color
uniform float scroll_speed : hint_range(0.0, 2.0) = 0.3;
void fragment() {
vec2 uv = UV;
uv.x += TIME * scroll_speed; // scroll horizontally over time
COLOR = texture(TEXTURE, uv) * tint; // TEXTURE = the node's texture
}
```
### 2. 2D dissolve using a noise threshold
```glsl
shader_type canvas_item;
uniform sampler2D noise : repeat_enable; // a NoiseTexture2D
uniform float amount : hint_range(0.0, 1.0) = 0.0;
void fragment() {
vec4 tex = texture(TEXTURE, UV);
float n = texture(noise, UV).r;
if (n < amount) {
discard; // cut the pixel away
}
COLOR = tex;
}
```
### 3. 3D (spatial): emissive rim light
```glsl
shader_type spatial;
uniform vec4 base_color : source_color = vec4(0.2, 0.5, 1.0, 1.0);
uniform vec3 rim_color : source_color = vec3(0.6, 0.8, 1.0);
uniform float rim_power : hint_range(0.5, 8.0) = 3.0;
void fragment() {
ALBEDO = base_color.rgb;
// VIEW and NORMAL are view-space built-ins; rim is strong at grazing angles.
float rim = pow(1.0 - dot(NORMAL, VIEW), rim_power);
EMISSION = rim_color * rim;
}
```
### 4. Screen-reading post effect (4.x hint, not SCREEN_TEXTURE)
```glsl
shader_type canvas_item;
// 4.x: declare the screen as a uniform with hint_screen_texture.
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
uniform float blur : hint_range(0.0, 4.0) = 1.0;
void fragment() {
vec2 px = SCREEN_PIXEL_SIZE * blur;
vec4 c = texture(screen_tex, SCREEN_UV);
c += texture(screen_tex, SCREEN_UV + vec2(px.x, 0.0));
c += texture(screen_tex, SCREEN_UV - vec2(px.x, 0.0));
COLOR = c / 3.0;
}
```
Set a uniform from GDScript:
```gdscript
$Sprite2D.material.set_shader_parameter("amount", 0.7)
```
## Pitfalls
- **3.x → 4.x renames.** `SCREEN_TEXTURE` is removed — declare
`uniform sampler2D x : hint_screen_texture;` and sample with `SCREEN_UV`. Color hints
`hint_color`/`hint_albedo`→`source_color`; `hint_white`/`hint_black`→
`hint_default_white`/`hint_default_black`; `hint_range` stays. Depth/normal use `hint_depth_texture` / `hint_normal_roughness_texture`.
- **Wrong output variable.** In `canvas_item` write `COLOR`; in `spatial` write `ALBEDO`
(and `EMISSION`, `ALPHA`, `ROUGHNESS`, `METALLIC`). Writing `COLOR` in a spatial shader
does nothing.
- **Color uniforms without `source_color`** are treated as raw linear values and look
wrong (washed/dark) because Godot won't sRGB-convert them.
- **Object drawn in the wrong order, casts no shadow, or skips SSAO (3D)** → the spatial
shader reads or writes `ALPHA`, which moves the whole material to the transparent
pipeline even if the value is always `1.0`. Don't touch `ALPHA` in opaque shaders; for
hard cut-outs also set `ALPHA_SCISSOR_THRESHOLD` (alpha-scissor stays in the opaque pass).
- **Sampling outside [0,1] UV** without `repeat_enable` clamps. Add `: repeat_enable` to
the sampler uniform for tiling/scroll.
- **Effect jumps once an hour** → `TIME` (seconds since start, affected by `time_scale`, not
by pausing) wraps every `rendering/limits/time/time_rollover_secs` (3600 by default).
Pick periods that divide the rollover, or feed your own time through a uniform.
- **`discard` is costly** on some hardware and breaks early-Z; prefer setting `ALPHA`/
`COLOR.a` when you can.
## References
- For built-in variables per shader type, render modes, `varying`, custom `light()`,
`vertex()` displacement, and the visual shader graph, read
`references/shading-language.md`.
## Related skills
- `shader-programming` — engine-agnostic shader concepts (GLSL/HLSL).
- `godot-3d-essentials` — materials, environment, and where spatial shaders live.
- `godot-ui-control` — applying shaders to UI for effects.
© gamedev-skills · Apache-2.0 · gamedev-skills/awesome-gamedev-agent-skills