如何在 Three.js 中编写自定义着色器(Shaders)

解决 Three.js 内置材质无法满足的个性化视觉需求:通过 GLSL 语言直接控制 GPU 渲染流程,实现如水波纹形变、菲涅尔光晕、溶解效果等高级视觉特效。

为什么需要这个技能

Three.js 提供的 MeshStandardMaterial 等内置材质虽然强大,但在面对极高性能要求的动态效果(如数万个顶点的实时波动)或特殊的艺术风格(如卡通渲染、能量场)时,由于其通用性,无法提供足够的灵活性。

通过编写着色器(Shader),你可以直接操纵顶点位置(Vertex Shader)和像素颜色(Fragment Shader),将计算压力转移到 GPU 上,实现电影级的实时视觉效果。

适用场景

  • 顶点形变:创建波动的水面、随风摆动的草地或扭曲的空间。
  • 自定义色彩:实现渐变色、基于高度的着色或复杂的噪声纹理。
  • 高级视觉特效:构建溶解(Dissolve)、边缘发光(Rim Lighting)或菲涅尔反射(Fresnel Effect)。
  • 材质扩展:在不重写整个材质的情况下,通过 onBeforeCompile 注入自定义逻辑。

核心工作流

1. 选择材质类型

  • ShaderMaterial:最常用,Three.js 会自动为你提供基础的 uniforms(如 projectionMatrix, modelViewMatrix)和属性(如 position, uv)。
  • RawShaderMaterial:完全控制,不提供任何内置变量,需手动声明所有属性。

2. 构建 Uniforms 与 Varyings

  • Uniforms:从 JS 传递到 GLSL 的全局变量(如时间 time、颜色 color),用于驱动动画。
  • Varyings:在顶点着色器中定义,将数据(如法线、UV)传递给片元着色器,并在两者之间进行线性插值。

3. 编写 GLSL 逻辑

  • 顶点着色器 (Vertex Shader):主要负责计算 gl_Position,决定物体形状。
  • 片元着色器 (Fragment Shader):主要负责计算 gl_FragColor,决定物体颜色。

4. 性能优化与调试

  • 使用 mix()step()smoothstep() 代替 if/else 分支,以提高 GPU 执行效率。
  • 通过将 gl_FragColor 设置为 vec4(vUv, 0.0, 1.0) 等方式进行视觉化调试。
import * as THREE from "three";

const material = new THREE.ShaderMaterial({
  uniforms: {
    time: { value: 0 },
    color: { value: new THREE.Color(0xff0000) },
  },
  vertexShader: `
    void main() {
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    uniform vec3 color;
    void main() {
      gl_FragColor = vec4(color, 1.0);
    }
  `,
});

下载和安装

下载 threejs-shaders 中文版 Skill ZIP

解压后将目录放入你的 AI 工具 skills 文件夹,重启工具后即可使用。具体路径参考内附的 USAGE.zh.md

你可能还需要

暂无推荐