关于 threejs-shaders
面向编写自定义 GPU 着色器或扩展内置材质的 Three.js 开发者技能。内容涵盖数据传递、GLSL 调试和性能检查,并在可行时保留现有 PBR 行为。
主要功能
- 01编写 ShaderMaterial 和 RawShaderMaterial 程序
- 02明确传递 uniform 与 varying
- 03通过 onBeforeCompile 扩展内置材质
- 04诊断 GLSL 和坐标空间问题
- 05检查着色器开销并释放自有资源
适用场景
- 01制作位移、菲涅耳、溶解或渐变效果
- 02保留内置 PBR 并添加局部效果
- 03排查着色器编译或视觉问题
- 04发布前检查 GPU 开销
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill threejs-shaders安装后在 Claude Code 中输入/threejs-shaders确认已加载。
附带文件evals/evals.jsonSKILL.toon
详细介绍
Three.js 着色器
使用此技能编写自定义 GPU 程序,以及安全地扩展内置材质。PBR 表面选择请交由 threejs-materials,纹理/UV 数据请交由 threejs-textures,全屏合成器效果请交由 threejs-postprocessing。
何时使用此技能
- 编写
ShaderMaterial或RawShaderMaterial顶点/片元程序 - 通过 uniform/varying 传递时间、颜色、纹理、变换或实例数据
- 实现位移、菲涅耳效果、溶解、渐变、噪声、边缘光或自定义效果
- 使用
onBeforeCompile扩展内置材质,同时保留其 PBR 行为 - 诊断 GLSL 编译、坐标空间、精度或 GPU 开销问题
说明
第 1 步:选择侵入性最小的着色器方案
| 需求 | 首选方案 |
|---|---|
| 完全自定义网格渲染 | ShaderMaterial |
| 完全控制声明和 Three.js 注入 | RawShaderMaterial |
| 保留 Standard/Physical PBR 并添加小型效果 | onBeforeCompile |
| 全屏屏幕空间处理 | 通过 threejs-postprocessing 使用 ShaderPass |
如果内置材质已经具备所需的光照/PBR 行为,请从内置材质开始。只有在视觉模型确实不同时,才使用自定义材质。
第 2 步:明确数据流
const material = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uColor: { value: new THREE.Color("#4f8cff") },
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform vec3 uColor;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(uColor * vec3(vUv.y), 1.0);
}
`,
});
uniform 在一次绘制调用中保持不变;varying 由顶点着色器写入,并插值到片元着色器中。在变量和注释中标明坐标空间(local、world、view、clip、uv)。大多数着色器错误都源于隐式的空间不匹配。
第 3 步:仅更新目标 uniform 值
material.uniforms.uTime.value = elapsedSeconds;
修改 .value;不要每帧替换 uniforms 对象。尽可能复用 Color、Vector 和纹理对象。对于实例间的差异,请使用受支持的属性,而不是为每个实例创建一个材质。
第 4 步:谨慎扩展内置材质
onBeforeCompile 依赖内部着色器代码块,这些代码块可能随 Three.js 版本修订而变化。保持替换范围小;如果程序变体取决于应用状态,请设置 material.customProgramCacheKey(),并针对锁定的项目版本进行测试。不要将源字符串替换作为永久抽象使用,除非有针对版本的测试环境。
第 5 步:验证编译、视觉效果和性能表现
- 检查浏览器着色器编译日志,并先精简为最小着色器,再调试细节。
- 至少用诊断颜色输出验证一种已知的坐标/法线/UV 情况。
- 如果产品支持,请在目标移动硬件上测试精度和导数。
- 发布前测量片元过度绘制、纹理采样、循环和材质变体。
- 在销毁时释放由功能模块拥有的自定义材质和渲染目标。
示例
菲涅耳边缘信号
在同一空间中计算并归一化法线和视线方向,然后根据二者的点积推导边缘项。测试正面和掠射角度;负值或错误的空间转换通常会导致菲涅耳效果反转,或固定在摄像机上。
顶点位移
在对象/局部空间中进行位移,并将变形后的位置/法线逻辑传递给一致的光照模型。高频位移需要足够密集的几何体;着色器无法生成网格中不存在的轮廓细节。
最佳实践
- 从只渲染纯色的最小着色器开始,然后逐步添加数据流。
- 明确说明坐标空间,仅在数学上确有需要时进行归一化。
- 确保渲染循环中的 uniform 更新不产生内存分配。
- 优先扩展内置材质,而不是重新实现 PBR 光照。
- 在目标 GPU 上进行性能分析;视觉上很小的片元效果也可能占用大量帧时间。