关于 shader-dev
shader-dev 是用于通过兼容 ShaderToy 的 GLSL 制作实时视觉效果的技能。它为着色器开发者提供技术指南、代码模板、技术选择建议,以及 WebGL2 适配和调试规则。
主要功能
- 01涵盖 36 种 GLSL 着色器技术的指南
- 02按效果需求匹配技术的建议
- 03实现步骤与代码模板
- 04ShaderToy 到 WebGL2 的适配规则
- 05GLSL 与 WebGL 调试指导
- 06渲染工作负载的性能限制
适用场景
- 01创建光线步进 3D 场景和 SDF 形状
- 02制作流体、粒子或海洋效果
- 03将 ShaderToy 着色器改为独立 WebGL2 页面
- 04排查 GLSL 编译和渲染问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ minimax-ai/ skills --skill shader-dev安装后在 Claude Code 中输入/shader-dev确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
reference/ambient-occlusion.mdanalytic-ray-tracing.mdanti-aliasing.mdatmospheric-scattering.mdcamera-effects.mdcellular-automata.mdcolor-palette.mdcsg-boolean-operations.mddomain-repetition.mddomain-warping.mdfluid-simulation.mdfractal-rendering.mdlighting-model.mdmatrix-transform.mdmultipass-buffer.mdnormal-estimation.mdparticle-system.mdpath-tracing-gi.mdpolar-uv-manipulation.mdpost-processing.mdprocedural-2d-pattern.mdprocedural-noise.mdray-marching.mdsdf-2d.mdsdf-3d.mdsdf-tricks.mdshadow-techniques.mdsimulation-physics.mdsound-synthesis.mdterrain-rendering.md详细介绍
Shader Craft
一套统一的技能,涵盖 36 种 GLSL 着色器技术(兼容 ShaderToy),用于实时视觉效果。
调用
/shader-dev <request>
$ARGUMENTS 包含用户的请求(例如“创建一个带柔和阴影的光线步进 SDF 场景”)。
技能结构
shader-dev/
├── SKILL.md # Core skill (this file)
├── techniques/ # Implementation guides (read per routing table)
│ ├── ray-marching.md # Sphere tracing with SDF
│ ├── sdf-3d.md # 3D signed distance functions
│ ├── lighting-model.md # PBR, Phong, toon shading
│ ├── procedural-noise.md # Perlin, Simplex, FBM
│ └── ... # 34 more technique files
└── reference/ # Detailed guides (read as needed)
├── ray-marching.md # Math derivations & advanced patterns
├── sdf-3d.md # Extended SDF theory
├── lighting-model.md # Lighting math deep-dive
├── procedural-noise.md # Noise function theory
└── ... # 34 more reference files
使用方法
- 阅读下方的技术路由表,确定与用户请求匹配的技术
- 阅读
techniques/中的相关文件——每个文件都包含核心原理、实现步骤和完整代码模板 - 如果需要深入了解(数学推导、高级模式),请访问每个技术文件底部指向
reference/的参考链接 - 生成独立 HTML 页面时,应用下方的 WebGL2 适配规则
技术路由表
| 用户想要创建…… | 主要技术 | 可结合使用 |
|---|---|---|
| 基于数学的 3D 对象 / 场景 | ray-marching + sdf-3d | lighting-model、shadow-techniques |
| 复杂的 3D 形状(布尔运算、混合) | csg-boolean-operations | sdf-3d、ray-marching |
| 3D 中无限重复的图案 | domain-repetition | sdf-3d、ray-marching |
| 有机 / 扭曲形状 | domain-warping | procedural-noise |
| 流体 / 烟雾 / 墨水效果 | fluid-simulation | multipass-buffer |
| 粒子效果(火焰、火花、雪) | particle-system | procedural-noise、color-palette |
| 基于物理的模拟 | simulation-physics | multipass-buffer |
| 生命游戏 / 反应扩散 | cellular-automata | multipass-buffer、color-palette |
| 海洋 / 水面 | water-ocean | atmospheric-scattering、lighting-model |
| 地形 / 景观 | terrain-rendering | atmospheric-scattering、procedural-noise |
| 云 / 雾 / 体积火焰 | volumetric-rendering | procedural-noise、atmospheric-scattering |
| 天空 / 日落 / 大气 | atmospheric-scattering | volumetric-rendering |
| 逼真光照(PBR、Phong) | lighting-model | shadow-techniques、ambient-occlusion |
| 阴影(软 / 硬) | shadow-techniques | lighting-model |
| 环境光遮蔽 | ambient-occlusion | lighting-model、normal-estimation |
| 路径追踪 / 全局光照 | path-tracing-gi | analytic-ray-tracing、multipass-buffer |
| 精确的射线与几何体求交 | analytic-ray-tracing | lighting-model |
| 体素世界(Minecraft 风格) | voxel-rendering | lighting-model、shadow-techniques |
| 噪声 / FBM 纹理 | procedural-noise | domain-warping |
| 平铺的 2D 图案 | procedural-2d-pattern | polar-uv-manipulation |
| Voronoi / 单元图案 | voronoi-cellular-noise | color-palette |
| 分形(Mandelbrot、Julia、3D) | fractal-rendering | color-palette、polar-uv-manipulation |
| 色彩分级 / 调色板 | color-palette | — |
| 泛光 / 色调映射 / 故障效果 | post-processing | multipass-buffer |
| 多通道乒乓缓冲区 | multipass-buffer | — |
| 纹理 / 采样技术 | texture-sampling | — |
| 摄像机 / 矩阵变换 | matrix-transform | — |
| 表面法线 | normal-estimation | — |
| 极坐标 / 万花筒 | polar-uv-manipulation | procedural-2d-pattern |
| 基于 SDF 的 2D 形状 / UI | sdf-2d | color-palette |
| 程序化音频 / 音乐 | sound-synthesis | — |
| SDF 技巧 / 优化 | sdf-tricks | sdf-3d、ray-marching |
| 抗锯齿渲染 | anti-aliasing | sdf-2d、post-processing |
| 景深 / 动态模糊 / 镜头效果 | camera-effects | post-processing、multipass-buffer |
| 高级纹理映射 / 无平铺纹理 | texture-mapping-advanced | terrain-rendering、texture-sampling |
| WebGL2 着色器错误 / 调试 | webgl-pitfalls | — |
技巧索引
几何与 SDF
- sdf-2d — 用于形状、UI 和抗锯齿渲染的二维有符号距离函数
- sdf-3d — 用于实时隐式曲面建模的三维有符号距离函数
- csg-boolean-operations — 构造实体几何:并集、差集、交集及平滑混合
- domain-repetition — 无限空间重复、折叠和有限平铺
- domain-warping — 用噪声扭曲域,生成有机、流动的形状
- sdf-tricks — SDF 优化、包围体、二分搜索细化、空心化、分层边缘、调试可视化
光线投射与光照
- ray-marching — 使用 SDF 进行球面追踪,以渲染 3D 场景
- analytic-ray-tracing — 光线与基本图元的闭式交点计算(球体、平面、长方体、环面)
- path-tracing-gi — 用于照片级真实感全局光照的蒙特卡洛路径追踪
- lighting-model — Phong、Blinn-Phong、PBR(Cook-Torrance)和卡通着色
- shadow-techniques — 硬阴影、软阴影(半影估算)、级联阴影
- ambient-occlusion — 基于 SDF 的 AO、屏幕空间 AO 近似
- normal-estimation — 有限差分法线、四面体技术
模拟与物理
- fluid-simulation — 包含平流、扩散和压力投影的 Navier-Stokes 流体求解器
- simulation-physics — 基于 GPU 的物理模拟:弹簧、布料、N 体引力、碰撞
- particle-system — 无状态和有状态粒子系统(火焰、雨、火花、星系)
- cellular-automata — 生命游戏、反应扩散(图灵图案)、沙子模拟
自然现象
- water-ocean — Gerstner 波、FFT 海洋、焦散、水下雾效
- terrain-rendering — 高度场光线步进、FBM 地形、侵蚀
- atmospheric-scattering — Rayleigh/Mie 散射、丁达尔光束、SSS 近似
- volumetric-rendering — 用于云、雾、火焰和爆炸的体积光线步进
程序化生成
- procedural-noise — 值噪声、Perlin、Simplex、Worley、FBM、脊状噪声
- procedural-2d-pattern — 砖块、六边形、truchet、伊斯兰几何图案
- voronoi-cellular-noise — Voronoi 图、Worley 噪声、龟裂大地、晶体
- fractal-rendering — Mandelbrot 集、Julia 集、3D 分形(Mandelbox、Mandelbulb)
- color-palette — 余弦调色板、HSL/HSV/Oklab、动态颜色映射
后期处理与基础设施
- post-processing — Bloom、色调映射(ACES、Reinhard)、暗角、色差、故障效果
- multipass-buffer — Ping-pong FBO 设置、跨帧状态持久化
- texture-sampling — 双线性、双三次、mipmap、程序化纹理查找
- matrix-transform — 摄像机 look-at、投影、旋转、轨道控制
- polar-uv-manipulation — 极坐标/对数极坐标、万花筒、螺旋映射
- anti-aliasing — SSAA、SDF 解析抗锯齿、时间抗锯齿(TAA)、FXAA 后期处理
- camera-effects — 景深(薄透镜)、运动模糊、镜头畸变、胶片颗粒、暗角
- texture-mapping-advanced — 双平面映射、避免纹理重复、光线微分滤波
音频
- sound-synthesis — GLSL 中的程序化音频:振荡器、包络、滤波器、FM 合成
调试与验证
- webgl-pitfalls — 常见 WebGL2/GLSL 错误:
fragCoord、main()包装器、函数顺序、宏限制、uniform 为空
WebGL2 适配规则
所有技巧文件均使用 ShaderToy GLSL 风格。生成独立 HTML 页面时,请应用以下适配:
着色器版本与输出
- 使用
canvas.getContext("webgl2") - 着色器首行:
#version 300 es,片段着色器添加precision highp float; - 片段着色器必须声明:
out vec4 fragColor; - 顶点着色器:
attribute→in,varying→out - 片段着色器:
varying→in,gl_FragColor→fragColor,texture2D()→texture()
片元坐标
- 使用
gl_FragCoord.xy,而不是fragCoord(WebGL2 没有内置的fragCoord)
// WRONG
vec2 uv = (2.0 * fragCoord - iResolution.xy) / iResolution.y;
// CORRECT
vec2 uv = (2.0 * gl_FragCoord.xy - iResolution.xy) / iResolution.y;
ShaderToy 模板的 main() 包装器
- ShaderToy 使用
void mainImage(out vec4 fragColor, in vec2 fragCoord) - WebGL2 要求使用标准的
void main()入口点 — 始终包装 mainImage:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// shader code...
fragColor = vec4(col, 1.0);
}
void main() {
mainImage(fragColor, gl_FragCoord.xy);
}
函数声明顺序
- GLSL 要求函数在使用前声明 — 请在使用前声明,或调整顺序:
// WRONG — getAtmosphere() calls getSunDirection() before it's defined
vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Error!
vec3 getSunDirection() { return normalize(vec3(1.0)); }
// CORRECT — define callee first
vec3 getSunDirection() { return normalize(vec3(1.0)); }
vec3 getAtmosphere(vec3 dir) { return getSunDirection(); } // Works
宏的限制
#define不能使用函数调用 — 请改用const:
// WRONG
#define SUN_DIR normalize(vec3(0.8, 0.4, -0.6))
// CORRECT
const vec3 SUN_DIR = vec3(0.756, 0.378, -0.567); // Pre-computed normalized value
提取 Script 标签
- 从
<script>标签提取着色器源码时,确保#version是第一个字符 — 使用.trim():
const fs = document.getElementById('fs').text.trim();
常见陷阱
- 未使用的 uniform:编译器可能会优化掉未使用的 uniform,导致
gl.getUniformLocation()返回null— 始终以编译器无法优化掉的方式使用 uniform - 循环索引:在循环中使用运行时常量;在某些 ES 版本中不要使用
#define宏 - 地形函数:
terrainM(vec2)之类的函数需要 XZ 分量 — 使用terrainM(pos.xz + offset),而不是terrainM(pos + offset)
HTML 页面设置
生成独立 HTML 页面时:
- Canvas 填满整个视口,并在窗口大小改变时自动调整
- 页面背景为黑色,不显示滚动条:
body { margin: 0; overflow: hidden; background: #000; } - 实现兼容 ShaderToy 的 uniform:
iTime、iResolution、iMouse、iFrame - 对于多通道效果(Buffer A/B),使用 WebGL2 帧缓冲区和乒乓缓冲(参见 multipass-buffer 技术)
常见陷阱
JS 变量声明顺序(TDZ — 会导致白屏崩溃)
let/const 变量必须在 <script> 代码块的顶部声明,且位于任何引用它们的函数之前:
// 1. State variables FIRST
let frameCount = 0;
let startTime = Date.now();
// 2. Canvas/GL init, shader compile, FBO creation
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl2');
// ...
// 3. Functions and event bindings LAST
function resize() { /* can now safely reference frameCount */ }
function render() { /* ... */ }
window.addEventListener('resize', resize);
原因:let/const 存在暂时性死区 — 在声明前引用它们会抛出 ReferenceError,导致白屏。
GLSL 编译错误(编写着色器后进行自检)
- 函数签名不匹配:调用必须与定义的参数数量和类型完全一致。如果定义为
float fbm(vec3 p),就不能使用vec2调用fbm(uv) - 将保留字用作变量名:请勿使用:
patch、cast、sample、filter、input、output、common、partition、active - 类型必须严格匹配:
vec3 x = 1.0不合法 — 请使用vec3 x = vec3(1.0);不能使用.z访问vec2 - 不能对结构体使用三元运算符:ESSL 不允许对结构体类型使用三元运算符 — 请改用
if/else
性能预算
部署环境可能使用 GPU 性能有限的无头软件渲染。请遵守以下限制:
- 光线步进主循环:≤ 128 步
- 体积采样 / 光照内循环:≤ 32 步
- FBM 八度:≤ 6 层
- 每像素嵌套循环总迭代次数:≤ 1000(超过此值会导致浏览器卡死)
快速配方
常见效果组合 — 由技术模块组装而成的完整渲染管线。
照片级 SDF 场景
- 几何体:sdf-3d(扩展基元)+ csg-boolean-operations(立方 / 四次 smin)
- 渲染:ray-marching + normal-estimation(四面体法)
- 光照:lighting-model(户外三光源模型)+ shadow-techniques(改进型软阴影)+ ambient-occlusion
- 大气:atmospheric-scattering(基于高度并带有阳光色调的雾效)
- 后期处理:post-processing(ACES 色调映射)+ anti-aliasing(2x SSAA)+ camera-effects(暗角)
有机 / 生物形态
- 几何体:sdf-3d(扩展基元 + 形变算子:扭曲、弯曲)+ csg-boolean(用于材质混合的梯度感知 smin)
- 细节:procedural-noise(带导数的 FBM)+ domain-warping
- 表面:lighting-model(通过 half-Lambert 近似次表面散射)
程序化景观
- 地形:terrain-rendering + procedural-noise(带导数的侵蚀 FBM)
- 纹理:texture-mapping-advanced(双平面映射 + 无平铺)
- 天空:atmospheric-scattering(Rayleigh/Mie + 高度雾)
- 水体:water-ocean(Gerstner 波)+ lighting-model(Fresnel 反射)
风格化 2D 艺术
- 形状:sdf-2d(扩展库)+ sdf-tricks(分层边缘、挖空)
- 颜色:color-palette(余弦调色板)+ polar-uv-manipulation(万花筒)
- 润色:anti-aliasing(SDF 分析抗锯齿)+ post-processing(泛光、色差)
Shader 调试技巧
可视化调试方法——临时替换输出以诊断问题。
| 检查项 | 代码 | 观察内容 |
|---|---|---|
| 表面法线 | col = nor * 0.5 + 0.5; | 平滑渐变 = 法线正确;出现条带 = epsilon 过大 |
| 光线步进次数 | col = vec3(float(steps) / float(MAX_STEPS)); | 红色热点 = 性能瓶颈;颜色均匀 = 迭代次数浪费 |
| 深度 / 距离 | col = vec3(t / MAX_DIST); | 验证命中距离是否正确 |
| UV 坐标 | col = vec3(uv, 0.0); | 检查坐标映射 |
| SDF 距离场 | col = (d > 0.0 ? vec3(0.9,0.6,0.3) : vec3(0.4,0.7,0.85)) * (0.8 + 0.2*cos(150.0*d)); | 可视化 SDF 条带和零交叉 |
| 棋盘格图案(UV) | col = vec3(mod(floor(uv.x*10.)+floor(uv.y*10.), 2.0)); | 验证 UV 扭曲和接缝 |
| 仅光照 | col = vec3(shadow); 或 col = vec3(ao); | 单独观察阴影 / AO 的贡献 |
| 材质 ID | col = palette(matId / maxMatId); | 验证材质分配 |
评论
支持 Markdown