主题
12 · WebGL 与 Shader 进阶
目标:在 Three.js 之上理解材质 / 后处理 / 简单自定义着色;知道何时不要手写裸 WebGL。
前置:03 · Three.js
1. 背景与目标
多数业务用 Three 的标准材质就够。Shader 是「亮点加分项」:能讲 vertex / fragment 分工,比堆插件列表更有说服力。
2. 核心概念
text
CPU (JS) 设好属性/uniform
→ GPU Vertex Shader(算顶点位置)
→ Fragment Shader(算像素颜色)1
2
3
2
3
| 层次 | 建议 |
|---|---|
MeshStandardMaterial 等 | 默认首选 |
ShaderMaterial / RawShaderMaterial | 特效、非标准光照 |
| 后处理(EffectComposer) | 全屏特效;贵,慎开 |
裸 webgl API | 学习用;工程优先 Three/Babylon |
3. 最小实践(Three 自定义色)
示意:片元里用 uniform 调色(完整 shader 以官方示例为准):
js
const mat = new THREE.ShaderMaterial({
uniforms: {
uColor: { value: new THREE.Color(0x4ea1ff) },
},
vertexShader: /* glsl */ `
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: /* glsl */ `
uniform vec3 uColor;
void main() {
gl_FragColor = vec4(uColor, 1.0);
}
`,
})1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
下一步可加 vUv、纹理采样、简单噪声。后处理先只开一种(如轻微 vignette)感受帧耗。
4. 踩坑与取舍
- 一上来写裸 WebGL:样板代码淹没学习目标。
- 后处理叠太多:移动端直接掉帧。
- 忘了精度与移动端差异:部分 extension / float 支持不一致。
- 特效掩盖结构:面试官更想听你何时不用 shader。
默认做法:标准材质 → 不够再 ShaderMaterial → 仍不够再考虑后处理。
5. 验收清单
- [ ] 能口述 vertex / fragment 分工
- [ ] 在 Three 里换过一次自定义材质或跟过官方 shader 示例
- [ ] 说清「何时不要上 WebGL」
- [ ] (可选)关掉后处理对比帧耗
6. 下一步
→ 13 · Web Workers 与 OffscreenCanvas
