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>
  )
}

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

延伸阅读

  • 批处理网格:允许同时渲染不同几何体
  • 骨骼动画:当前不支持实例化
  • 变形动画:实例支持但批处理网格不支持
相关推荐
一叶飘零_sweeeet6 分钟前
IDEA 插件 Trae AI 全攻略
java·人工智能·intellij-idea
SEO_juper30 分钟前
AI 搜索时代:引领变革,重塑您的 SEO 战略
人工智能·搜索引擎·seo·数字营销·seo优化
shengyicanmou1 小时前
深度解码格行无缝切网引擎:40%延迟降低背后的多网智能切换架构
人工智能·物联网·智能硬件
Hello123网站1 小时前
GLM-4-Flash:智谱AI推出的首个免费API服务,支持128K上下文
人工智能·ai工具
试剂界的爱马仕2 小时前
胶质母细胞瘤对化疗的敏感性由磷脂酰肌醇3-激酶β选择性调控
人工智能·科技·算法·机器学习·ai写作
青岛佰优联创新科技有限公司2 小时前
移动板房的网络化建设
服务器·人工智能·云计算·智慧城市
双向332 小时前
私有化部署全攻略:开源模型本地化改造的性能与安全评测
人工智能
189228048612 小时前
NY243NY253美光固态闪存NY257NY260
大数据·网络·人工智能·缓存
AI波克布林2 小时前
发文暴论!线性注意力is all you need!
人工智能·深度学习·神经网络·机器学习·注意力机制·线性注意力
张子夜 iiii2 小时前
机器学习算法系列专栏:主成分分析(PCA)降维算法(初学者)
人工智能·python·算法·机器学习