Skip to content

一次 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 中输出固定颜色,验证宏分支是否正确工作

小结

你已经掌握了实例化渲染的基本用法。下一节我们将用噪声函数生成程序化纹理,让画面在不依赖图片的情况下仍然拥有丰富细节。