godot-shaders-basics by thedivergentai/gd-agentic-skills
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-shaders-basics片段/顶点着色器、uniform 变量和内置变量用于定义自定义视觉效果。
专家级着色器模板,包含参数验证和常见效果模式。
无需 AnimationPlayer 的运行时着色器 uniform 动画 - 用于动态效果。
基于遮罩的高性能溶解效果。使用 ALPHA_SCISSOR 以启用深度预通道优化和阴影投射。
适合批处理的受击闪光效果。使用 instance uniform 允许在一次绘制调用中实现数千个独特的闪光效果。
用于风格化屏幕输出的后处理逻辑。使用 hint_screen_texture 和优化的坐标量化。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
在 vertex() 函数中使用 NoiseTexture2D 进行程序化几何体置换,用于起伏地形。
使用 world_vertex_coords 的 GPU 驱动风动画,实现整个环境中的统一摇摆效果。
使用 global uniform 的世界交互模式。同步玩家位置以在整个项目中压平草地。
专家级深度缓冲区逻辑。从 hint_depth_texture 重建世界空间坐标,用于水/雾效果。
无需 UV 的纹理映射架构。沿世界轴无缝投影纹理,用于程序化悬崖和岩石。
绕过批处理限制。将 sampler2DArray 与 instance uniform 结合,为数千个批处理对象提供独特纹理。
Godot 4.3 特定的全矩形着色器。处理反转 Z 坐标重建,以防止在近平面处发生裁剪。
discard 进行优化 — 这会阻止深度预通道有效工作。被丢弃的像素仍然消耗顶点处理成本;有时不渲染对象反而更好 [1]。if/else 处理动态状态 — GPU 讨厌分支。使用 mix()、step() 和 smoothstep() 进行数学化、硬件优化的选择 [5, 21]。if (v == 0.5) 不可靠。使用 abs(a - b) < epsilon 或 step()。POSITION 为 vec4(VERTEX, 1.0) — Godot 4.3 使用反转 Z 深度;这会导致裁剪。使用 POSITION = vec4(VERTEX.xy, 1.0, 1.0) [8, 9]。instance uniform。这允许为数千个节点设置唯一值,同时保持单个绘制调用(批处理)[10]。TIME — 片段速度应可通过 uniform 变量控制,以确保不同游戏状态间的一致性。hint_source_color — 没有它,引擎会将颜色视为线性数学计算,导致检查器中伽马值不正确和视觉发白。fragment() 中计算本可以在 vertex() 中计算的复杂数学运算 — vertex() 每个点运行一次;fragment() 每帧运行数百万次。应通过 varying 插值传递值。#define 宏进行动态运行时切换 — 这会创建新的着色器变体,在游戏中首次遇到时导致大量编译卡顿。应改用 uniform 变量。reflect(dir, normal) 会导致严重的渲染伪影和错误的光照计算。fract() 的情况下修改 UV — 在没有 repeat 环绕或钳位的情况下将 UV 偏移超出 0.0-1.0 范围,将采样边缘像素或返回黑色,破坏纹理一致性。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);
}
应用到 Sprite:
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;
}
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);
}
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;
}
shader_type spatial;
void fragment() {
ALBEDO = vec3(1.0, 0.0, 0.0); // Red material
}
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;
}
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;
}
// 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)
2D (canvas_item):
UV - 纹理坐标 (0-1)COLOR - 输出颜色TEXTURE - 当前纹理TIME - 自开始以来的时间SCREEN_UV - 屏幕坐标3D (spatial):
ALBEDO - 基础颜色NORMAL - 表面法线ROUGHNESS - 表面粗糙度METALLIC - 金属度值// ✅ 良好 - 可调整
uniform float speed = 1.0;
void fragment() {
COLOR.r = sin(TIME * speed);
}
// ❌ 不佳 - 硬编码
void fragment() {
COLOR.r = sin(TIME * 2.5);
}
// Avoid expensive operations in fragment shader
// Pre-calculate values when possible
// Use textures for complex patterns
// Water wave effect
// Creates horizontal distortion based on sine wave
uniform float wave_amplitude = 0.02;
每周安装数
114
仓库
GitHub 星标数
59
首次出现
2026年2月10日
安全审计
安装于
gemini-cli112
codex111
opencode111
github-copilot108
kimi-cli108
amp108
Fragment/vertex shaders, uniforms, and built-in variables define custom visual effects.
Expert shader template with parameter validation and common effect patterns.
Runtime shader uniform animation without AnimationPlayer - for dynamic effects.
High-performance mask-based dissolve. Uses ALPHA_SCISSOR to enable depth-prepass optimization and shadow casting.
Batch-friendly hit effects. Uses instance uniform to allow thousands of unique flashes in one draw call.
Post-processing logic for stylizing screen output. Uses hint_screen_texture and optimized coordinate quantization.
Procedural geometry displacement using NoiseTexture2D in the vertex() function for rolling terrain.
GPU-driven wind animation using world_vertex_coords for uniform sway across the environment.
World-interaction pattern using global uniform. Synchronizes player position to push grass down project-wide.
Expert depth-buffer logic. Reconstructs world-space coordinates from hint_depth_texture for water/fog effects.
UV-less texturing architecture. Seamlessly projects textures along world axes for procedural cliffs and rocks.
Bypassing batching limits. Combines sampler2DArray with instance uniform to give unique textures to thousands of batched objects.
Godot 4.3 specific full-rect shader. Handles Reversed-Z coordinate reconstruction to prevent clipping at the near plane.
discard unconditionally for optimization — It prevents the depth prepass from working effectively. A discarded pixel still costs vertex processing; sometimes not rendering the object is better [1].if/else for dynamic states in high-performance shaders — GPUs hate branching. Use mix(), step(), and smoothstep() for mathematical, hardware-optimized selection [5, 21].if (v == 0.5) is unreliable. Use abs(a - b) < epsilon or step().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:
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;
}
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);
}
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;
}
shader_type spatial;
void fragment() {
ALBEDO = vec3(1.0, 0.0, 0.0); // Red material
}
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;
}
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;
}
// 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)
2D (canvas_item):
UV - Texture coordinates (0-1)COLOR - Output colorTEXTURE - Current textureTIME - Time since startSCREEN_UV - Screen coordinates3D (spatial):
ALBEDO - Base colorNORMAL - Surface normalROUGHNESS - Surface roughnessMETALLIC - Metallic value// ✅ Good - adjustable
uniform float speed = 1.0;
void fragment() {
COLOR.r = sin(TIME * speed);
}
// ❌ Bad - hardcoded
void fragment() {
COLOR.r = sin(TIME * 2.5);
}
// Avoid expensive operations in fragment shader
// Pre-calculate values when possible
// Use textures for complex patterns
// Water wave effect
// Creates horizontal distortion based on sine wave
uniform float wave_amplitude = 0.02;
Weekly Installs
114
Repository
GitHub Stars
59
First Seen
Feb 10, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli112
codex111
opencode111
github-copilot108
kimi-cli108
amp108
Minecraft旧版主机版C++重制项目 - 支持模组开发、局域网联机和专用服务器
551 周安装
POSITION to vec4(VERTEX, 1.0) for full-screen quads in 4.3+ — Godot 4.3 uses Reversed-Z depth; this will cause clipping. Use POSITION = vec4(VERTEX.xy, 1.0, 1.0) [8, 9].instance uniform. This allows unique values for thousands of nodes while maintaining a single draw call (batching) [10].TIME without a speed multiplier — Fragment speed should be controllable via uniforms to ensure consistency across different gameplay states.hint_source_color for color uniforms — Without it, the engine treats colors as linear math, leading to incorrect gamma and washed-out visuals in the inspector.fragment() that could be in vertex() — vertex() runs once per point; fragment() runs millions of times per frame. Interpolate values via varying instead.#define macros for dynamic runtime toggles — These create new shader permutations, causing massive compilation stutters when first encountered in-game. Use uniforms instead.reflect(dir, normal) on unnormalized vectors causes severe rendering artifacts and incorrect lighting math.fract() — Shifting UVs beyond 0.0-1.0 without repeat wrapping or clamping will sample edge pixels or return black, breaking texture consistency.