Three.js实例化技术:高效渲染数千3D对象

Three.js实例化技术:同时渲染多个3D对象

学习如何使用React Three Fiber中的实例化技术高效渲染数千个3D对象,正如性能优化的basement.studio网站所展示的那样。

引言

实例化是一种性能优化技术,允许你同时渲染共享相同几何体和材质的多个对象。如果需要渲染森林场景,你会需要大量的树木、岩石和草地。如果它们共享相同的基础网格和材质,你就可以通过单次绘制调用渲染所有对象。

绘制调用是CPU向GPU发出的绘制指令,比如绘制一个网格。每个独特的几何体或材质通常需要自己的调用。过多的绘制调用会损害性能。实例化通过将多个副本批量处理为一个来减少这种情况。

基础实例化

让我们从一个传统方式渲染一千个方块的例子开始:

javascript 复制代码
const boxCount = 1000

function Scene() {
  return (
    <>
      {Array.from({ length: boxCount }).map((_, index) => (
        <mesh
          key={index}
          position={getRandomPosition()}
          scale={getRandomScale()}
        >
          <boxGeometry />
          <meshBasicMaterial color={getRandomColor()} />
        </mesh>
      ))}
    </>
  )
}

查看示例 | 源代码

如果添加性能监视器,会发现"calls"数量与boxCount匹配。

使用drei/instances可以快速实现实例化:

javascript 复制代码
import { Instance, Instances } from "@react-three/drei"

const boxCount = 1000

function Scene() {
  return (
    <Instances limit={boxCount}>
      <boxGeometry />
      <meshBasicMaterial />
      {Array.from({ length: boxCount }).map((_, index) => (
        <Instance
          key={index}
          position={getRandomPosition()}
          scale={getRandomScale()}
          color={getRandomColor()}
        />
      ))}
    </Instances>
  )
}

现在"calls"减少到1,即使我们显示了一千个方块。

多组实例

要渲染森林场景,可能需要不同的实例组:

javascript 复制代码
import { createInstances } from "@react-three/drei"

const boxCount = 1000
const sphereCount = 1000

const [CubeInstances, Cube] = createInstances()
const [SphereInstances, Sphere] = createInstances()

function InstancesProvider({ children }: { children: React.ReactNode }) {
  return (
    <CubeInstances limit={boxCount}>
      <boxGeometry />
      <meshBasicMaterial />
      <SphereInstances limit={sphereCount}>
        <sphereGeometry />
        <meshBasicMaterial />
        {children}
      </SphereInstances>
    </CubeInstances>
  )
}

自定义着色器实例

要为自定义着色器添加实例支持:

javascript 复制代码
const baseMaterial = new THREE.RawShaderMaterial({
  vertexShader: /*glsl*/ `
    attribute vec3 position;
    attribute vec3 instanceColor;
    attribute vec3 normal;
    attribute vec2 uv;
    uniform mat4 modelMatrix;
    uniform mat4 viewMatrix;
    uniform mat4 projectionMatrix;
    attribute mat4 instanceMatrix;

    uniform float uTime;
    uniform float uAmplitude;

    vec3 movement(vec3 position) {
      vec3 pos = position;
      pos.x += sin(position.y + uTime) * uAmplitude;
      return pos;
    }

    void main() {
      vec3 blobShift = movement(position);
      vec4 modelPosition = modelMatrix * instanceMatrix * vec4(blobShift, 1.0);
      vec4 viewPosition = viewMatrix * modelPosition;
      vec4 projectionPosition = projectionMatrix * viewPosition;
      gl_Position = projectionPosition;
    }
  `,
  fragmentShader: /*glsl*/ `
    void main() {
      gl_FragColor = vec4(1, 0, 0, 1);
    }
  `
})

创建森林场景

使用实例化网格创建森林场景:

javascript 复制代码
const [TreeInstances, Tree] = createInstances()
const treeCount = 1000

function Scene() {
  const { scene, nodes } = useGLTF(
    "/stylized_pine_tree_tree.glb"
  ) as unknown as TreeGltf

  return (
    <group>
      <TreeInstances
        limit={treeCount}
        scale={0.02}
        geometry={nodes.tree_low001_StylizedTree_0.geometry}
        material={nodes.tree_low001_StylizedTree_0.material}
      >
        {Array.from({ length: treeCount }).map((_, index) => (
          <Tree key={index} position={getRandomPosition()} />
        ))}
      </TreeInstances>
    </group>
  )
}

整个森林仅用三次绘制调用渲染:天空盒一次,地面平面一次,所有树木一次。

延伸阅读

  • 批处理网格:允许同时渲染不同几何体
  • 骨骼动画:当前不支持实例化
  • 变形动画:实例支持但批处理网格不支持
相关推荐
小陈同学呦几秒前
Mac 本地部署 Ollama 并运行 Gemma 4 模型
aigc
happyprince18 分钟前
2026年04月12日热门Model/github项目
人工智能
网教盟人才服务平台18 分钟前
AI 全面重塑网络攻防生态,智能安全进入深度对抗时代
网络·人工智能·安全
w_t_y_y20 分钟前
python类库(二)输出解析
人工智能
sinat_2869451923 分钟前
AI Coding 时代的 TDD:从理念到工程落地
人工智能·深度学习·算法·tdd
爱吃的小肥羊32 分钟前
2026 最新 Codex 如何使用指南:ChatGPT 订阅、CLI 安装、App 登录全流程
aigc·ai编程
ASKED_201933 分钟前
从排序到生成:腾讯广告算法大赛 2025 baseline解读
人工智能·算法
阿杰学AI1 小时前
AI核心知识115—大语言模型之 自监督学习(简洁且通俗易懂版)
人工智能·学习·ai·语言模型·aigc·监督学习·自监督学习
IT_陈寒1 小时前
为什么我的JavaScript异步回调总是乱序执行?
前端·人工智能·后端
Zzj_tju1 小时前
大语言模型技术指南:Transformer 为什么能成为基础架构?核心模块与参数怎么理解
人工智能·语言模型·transformer