一次 DrawCall 画很多物体
当场景中有成百上千个相同几何体时,逐个创建 Mesh 并逐个绘制会带来大量 drawcall 开销。本节我们使用 Instancing(实例化渲染):在一次 drawcall 中绘制多个实例,从而显著降低 CPU 负担。
目标
- 使用
InstancedMesh绘制大量相同几何体 - 理解
instanceMatrix:每个实例各自的变换矩阵 - 使用
instanceColor:每个实例一份的颜色数据(可选)
代码要点
文件:CustomInstancedCubes.ts
InstancedMesh会为ShaderMaterial自动注入 instancing 所需的 attribute(包括instanceMatrix)。因此不要在 shader 里重复声明:
glsl
// 不要这样做:attribute mat4 instanceMatrix;- 我们通过
mesh.instanceColor = new THREE.InstancedBufferAttribute(...)提供每实例颜色。Three.js 会据此启用相关宏,shader 里可直接使用instanceColor(并用#ifdef USE_INSTANCING_COLOR兼容兜底)。
你应当看到什么
屏幕中出现大量小立方体,它们有不同的颜色,并且在时间驱动下产生轻微起伏动画。注意:动画是在顶点着色器里完成的,因此几乎不增加 drawcall。
动手练习
- 把实例数量从
400改成2000,观察帧率变化(并与非 instancing 的写法对比) - 把位移公式里的
offset权重调大,让每个实例的运动差异更明显 - 去掉
instanceColor,并在 shader 中输出固定颜色,验证宏分支是否正确工作
小结
你已经掌握了实例化渲染的基本用法。下一节我们将用噪声函数生成程序化纹理,让画面在不依赖图片的情况下仍然拥有丰富细节。
