返回 Skills 目錄
gamedev-skills/awesome-gamedev-agent-skills已通過檢查

SKILL DETAIL

godot-shaders

gamedev-skills/awesome-gamedev-agent-skills/godot-shaders

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.

安裝量 · 301查看來源

Installation

npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-shaders

技能檔案

SKILL.md

最近同步 · 2026年10月22日

references/shading-language.md›
# Godot Shading Language reference (Godot 4.7)

Depth companion to `godot-shaders`. The language is GLSL-like with engine built-ins.

## Shader types and processor functions

| `shader_type` | Used by | Main functions | Key output writes |
|---------------|---------|----------------|-------------------|
| `canvas_item` | 2D `CanvasItem` materials | `vertex`, `fragment`, `light` | `COLOR` |
| `spatial` | 3D `Mesh`/surface materials | `vertex`, `fragment`, `light` | `ALBEDO`, `EMISSION`, `ALPHA`, `ROUGHNESS`, `METALLIC`, `NORMAL_MAP` |
| `particles` | `GPUParticles` process | `start`, `process` | `VELOCITY`, `TRANSFORM`, `COLOR` |
| `sky` | `Sky` material | `sky` | `COLOR` |
| `fog` | `FogVolume` | `fog` | `DENSITY`, `ALBEDO`, `EMISSION` |

## Common built-ins

canvas_item: `UV`, `COLOR`, `TEXTURE`, `TEXTURE_PIXEL_SIZE`, `SCREEN_UV`,
`SCREEN_PIXEL_SIZE`, `VERTEX`, `TIME`, `POINT_COORD`, `MODELVIEW_MATRIX`.

spatial: `VERTEX` (model/local), `NORMAL`, `TANGENT`, `UV`, `UV2`, `VIEW`, `ALBEDO`,
`ALPHA`, `EMISSION`, `ROUGHNESS`, `METALLIC`, `SPECULAR`, `NORMAL_MAP`, `TIME`,
`CAMERA_POSITION_WORLD`, `MODEL_MATRIX`, `VIEW_MATRIX`, `PROJECTION_MATRIX`, `FRAGCOORD`.

## Uniform hints (4.x)

```glsl
uniform float speed : hint_range(0.0, 1.0) = 0.5;
uniform float gain  : hint_range(0.0, 2.0, 0.01);     // min, max, step
uniform vec4 col    : source_color = vec4(1.0);       // sRGB color picker
uniform sampler2D tex : source_color, filter_linear_mipmap, repeat_enable;
uniform sampler2D screen_tex : hint_screen_texture, filter_linear_mipmap;
uniform sampler2D depth_tex  : hint_depth_texture;
uniform sampler2D normal_rough : hint_normal_roughness_texture;
group_uniforms Movement;                               // Inspector grouping
uniform float amplitude = 1.0;
```

Sampler filter/repeat qualifiers: `filter_nearest`, `filter_linear`,
`filter_nearest_mipmap`, `filter_linear_mipmap`, `repeat_enable`, `repeat_disable`.

Set from code: `material.set_shader_parameter("name", value)`;
read with `get_shader_parameter("name")`.

## Render modes

First-line modifiers after the type, comma-separated:

- spatial: `unshaded`, `cull_disabled`, `cull_front`, `depth_draw_opaque`,
  `depth_test_disabled`, `blend_add`, `blend_mul`, `diffuse_toon`, `specular_toon`,
  `world_vertex_coords`, `vertex_lighting`, `shadows_disabled`, `ambient_light_disabled`.
- canvas_item: `blend_mix` (default), `blend_add`, `blend_sub`, `blend_mul`,
  `blend_premul_alpha`, `unshaded`, `light_only`.

```glsl
shader_type spatial;
render_mode unshaded, cull_disabled;
```

## varying (pass data vertex -> fragment)

```glsl
varying vec3 world_pos;
void vertex()   { world_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
void fragment() { ALBEDO = fract(world_pos); }
```

## vertex() displacement

```glsl
void vertex() {
    VERTEX.y += sin(VERTEX.x * 4.0 + TIME * 2.0) * 0.1;   // wave the mesh
}
```

## Custom light() (toon ramp example, spatial)

```glsl
void light() {
    float ndl = dot(NORMAL, LIGHT);
    float ramp = step(0.0, ndl);                 // hard two-tone
    DIFFUSE_LIGHT += ALBEDO * LIGHT_COLOR.rgb * ramp * ATTENUATION;
}
```

## 2D normal maps

For lit 2D, write `NORMAL_MAP` in a `canvas_item` fragment (or assign a normal map on the
node) and add a `Light2D`/`PointLight2D` to the scene; `light()` controls the response.

## Visual shaders

`VisualShader` lets you build the same graphs node-by-node and exports to this language.
Useful for iteration; the generated code is standard Godot Shading Language. Convert to a
text `.gdshader` when you need precise control or version it in source.

## Performance notes

- Texture fetches and `discard` are the most expensive common operations; minimize both.
- Branch on uniforms (constant per draw) is cheap; branch on per-pixel values can be slow.
- Precompute in `vertex()` and pass via `varying` when a value is linear across a triangle.
- Prefer `mix()`, `step()`, `smoothstep()`, `clamp()` over `if` for per-pixel selection.
SKILL.md›
---
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`→`source_color`; `hint_albedo`/`hint_white`→`source_color`;
  `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.
- **Transparency needs opt-in (3D).** For `ALPHA < 1.0` to blend, add a render mode or set
  the material transparency; otherwise it's opaque/cut.
- **Sampling outside [0,1] UV** without `repeat_enable` clamps. Add `: repeat_enable` to
  the sampler uniform for tiling/scroll.
- **`TIME` is seconds since start** and keeps growing — wrap with `fract()`/`mod()` for
  periodic effects to avoid precision drift.
- **`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.