godot-shaders-basics

Expert blueprint for shader programming (visual effects, post-processing, material customization) using Godot's GLSL-like shader language. Covers canvas_item (2D), spatial (3D), uniforms, built-in variables, and performance. Use when implementing custom effects OR stylized rendering. Keywords shader, GLSL, fragment, vertex, canvas_item, spatial, uniform, UV, COLOR, ALBEDO, post-processing.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "godot-shaders-basics" with this command: npx skills add thedivergentai/gd-agentic-skills/thedivergentai-gd-agentic-skills-godot-shaders-basics

Shader Basics

Fragment/vertex shaders, uniforms, and built-in variables define custom visual effects.

Available Scripts

vfx_port_shader.gdshader

Expert shader template with parameter validation and common effect patterns.

shader_parameter_animator.gd

Runtime shader uniform animation without AnimationPlayer - for dynamic effects.

NEVER Do in Shaders

  • NEVER use expensive operations in fragment()pow(), sqrt(), sin() on every pixel? 1920x1080 = 2M calls/frame = lag. Pre-calculate OR use texture lookups.
  • NEVER forget to normalize vectorsreflect(direction, normal) without normalization? Wrong reflections + rendering artifacts. ALWAYS normalize direction vectors.
  • NEVER use if/else for branching — GPUs hate branching (SIMD architecture). Use mix(), step(), smoothstep() for conditional logic.
  • NEVER modify UV without bounds checkUV.x += 10.0 goes outside 0-1 range? Texture sampling breaks. Use fract() OR clamp().
  • NEVER use TIME without deltaCOLOR.a = sin(TIME) runs at variable speed on different framerates. Use TIME * speed_factor for consistent animation.
  • NEVER forget hint_source_color for colorsuniform vec4 tint without hint? Inspector shows raw floats. Use uniform vec4 tint : source_color for color picker.

shader_type canvas_item;

void fragment() {
    // Get texture color
    vec4 tex_color = texture(TEXTURE, UV);
    
    // Tint red
    COLOR = tex_color * vec4(1.0, 0.5, 0.5, 1.0);
}

Apply to Sprite:

  1. Select Sprite2D node
  2. Material → New ShaderMaterial
  3. Shader → New Shader
  4. Paste code

Common 2D Effects

Dissolve Effect

shader_type canvas_item;

uniform float dissolve_amount : hint_range(0.0, 1.0) = 0.0;
uniform sampler2D noise_texture;

void fragment() {
    vec4 tex_color = texture(TEXTURE, UV);
    float noise = texture(noise_texture, UV).r;
    
    if (noise < dissolve_amount) {
        discard;  // Make pixel transparent
    }
    
    COLOR = tex_color;
}

Wave Distortion

shader_type canvas_item;

uniform float wave_speed = 2.0;
uniform float wave_amount = 0.05;

void fragment() {
    vec2 uv = UV;
    uv.x += sin(uv.y * 10.0 + TIME * wave_speed) * wave_amount;
    
    COLOR = texture(TEXTURE, uv);
}

Outline

shader_type canvas_item;

uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
uniform float outline_width = 2.0;

void fragment() {
    vec4 col = texture(TEXTURE, UV);
    vec2 pixel_size = TEXTURE_PIXEL_SIZE * outline_width;
    
    float alpha = col.a;
    alpha = max(alpha, texture(TEXTURE, UV + vec2(pixel_size.x, 0.0)).a);
    alpha = max(alpha, texture(TEXTURE, UV + vec2(-pixel_size.x, 0.0)).a);
    alpha = max(alpha, texture(TEXTURE, UV + vec2(0.0, pixel_size.y)).a);
    alpha = max(alpha, texture(TEXTURE, UV + vec2(0.0, -pixel_size.y)).a);
    
    COLOR = mix(outline_color, col, col.a);
    COLOR.a = alpha;
}

3D Shaders

Basic 3D Shader

shader_type spatial;

void fragment() {
    ALBEDO = vec3(1.0, 0.0, 0.0);  // Red material
}

Toon Shading (Cel-Shading)

shader_type spatial;

uniform vec3 base_color : source_color = vec3(1.0);
uniform int color_steps = 3;

void light() {
    float NdotL = dot(NORMAL, LIGHT);
    float stepped = floor(NdotL * float(color_steps)) / float(color_steps);
    
    DIFFUSE_LIGHT = base_color * stepped;
}

Screen-Space Effects

Vignette

shader_type canvas_item;

uniform float vignette_strength = 0.5;

void fragment() {
    vec4 color = texture(TEXTURE, UV);
    
    // Distance from center
    vec2 center = vec2(0.5, 0.5);
    float dist = distance(UV, center);
    
    float vignette = 1.0 - dist * vignette_strength;
    
    COLOR = color * vignette;
}

Uniforms (Parameters)

// Float slider
uniform float intensity : hint_range(0.0, 1.0) = 0.5;

// Color picker
uniform vec4 tint_color : source_color = vec4(1.0);

// Texture
uniform sampler2D noise_texture;

// Access in code:
material.set_shader_parameter("intensity", 0.8)

Built-in Variables

2D (canvas_item):

  • UV - Texture coordinates (0-1)
  • COLOR - Output color
  • TEXTURE - Current texture
  • TIME - Time since start
  • SCREEN_UV - Screen coordinates

3D (spatial):

  • ALBEDO - Base color
  • NORMAL - Surface normal
  • ROUGHNESS - Surface roughness
  • METALLIC - Metallic value

Best Practices

1. Use Uniforms for Tweaking

// ✅ Good - adjustable
uniform float speed = 1.0;

void fragment() {
    COLOR.r = sin(TIME * speed);
}

// ❌ Bad - hardcoded
void fragment() {
    COLOR.r = sin(TIME * 2.5);
}

2. Optimize Performance

// Avoid expensive operations in fragment shader
// Pre-calculate values when possible
// Use textures for complex patterns

3. Comment Shaders

// Water wave effect
// Creates horizontal distortion based on sine wave
uniform float wave_amplitude = 0.02;

Reference

Related

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

godot-genre-idle-clicker

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-master

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-ui-theming

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

godot-particles

No summary provided by upstream source.

Repository SourceNeeds Review