gpt4 book ai didi

three.js - ThreeJS中的InstancedBufferGeometry和InstancedMesh有什么区别?

转载 作者:行者123 更新时间:2023-12-03 23:49:15 26 4
gpt4 key购买 nike

以下是他们的文件:

实例网格 : https://threejs.org/docs/#api/en/objects/InstancedMesh

InstancedBufferGeometry : https://threejs.org/docs/#api/en/core/InstancedBufferGeometry

这里也有一些例子:
https://github.com/mrdoob/three.js/blob/dev/examples/webgl_buffergeometry_instancing.html

我一般都知道threejs和WebGL中关于“实例化”的基本概念。
我目前的理解是 Mesh 由 Geometry 组成和 Material (例如 const plane = new THREE.Mesh(geometry, material) )。几何不包含颜色,但 Material 包含。

从上面的例子中,我看到他们把颜色属性放在 InstancedBufferGeometry ,这很令人困惑......几何不应该有颜色,对吧?我错了吗?

geometry.setAttribute( 'offset', new THREE.InstancedBufferAttribute( new Float32Array( offsets ), 3 ) );
geometry.setAttribute( 'color', new THREE.InstancedBufferAttribute( new Float32Array( colors ), 4 ) );
geometry.setAttribute( 'orientationStart', new THREE.InstancedBufferAttribute( new Float32Array( orientationsStart ), 4 ) );
geometry.setAttribute( 'orientationEnd', new THREE.InstancedBufferAttribute( new Float32Array( orientationsEnd ), 4 ) );

我的问题是,如果我想渲染 1000 个不同颜色的方形平面并独立移动,我应该使用 InstancedMeshInstancedBufferGeometry ?为什么?它们可以一起使用吗?

最佳答案

好吧,顺便说一句,我已经完成了@pailhead 的 Medium 文章三部曲,感谢您的演练!
以下是我对此时使用InstancedMesh的好情况的理解:
如果您的部分或全部实例会经常更改,并且您的实例少于 ~50K,并且实例之间的差异可以通过 TRS 变换(或颜色)来描述,那么 InstancedMesh 应该非常适合您。
如果您的大多数实例都是静态的,并且您一次只能更新几个,那么您的实例数量可能是无限的(直到您达到 GPU 渲染瓶颈或 VRAM 大小)。
我通过观察几个示例的行为得出了这些值,并通过一些探索来扩大实例计数:https://codesandbox.io/s/r3f-instanced-colors-8fo01
我认为这个 R3F 示例包含足够的“额外内容”来引入足够的开销以更接近于真实的应用程序。
通过查看 Chrome 中的性能选项卡,我发现您将大部分时间花在主 CPU 线程上(请记住,可能会将这项工作 fork 给工作线程)处理 updateMatrix 调用和像这样的东西。基本上,如果您尝试在主线程上旋转超过 50,000 个对象中的每一个,那么您的应用程序在典型系统上根本无法正常运行,那么您的 CPU 需要大量的三角函数来计算每一帧!由于 InstancedMesh 接口(interface),这将极大地限制 CPU,它使您可以自由地为每个实例分配变换(以及可选的颜色)。
如果您确实需要在每一帧中转换每个实例,您可能需要考虑是否可以将转换计算卸载到 GPU 本身,执行此操作的标准方法是使用顶点着色器。与一个 cpu 线程相比,使用顶点着色器可以完成的额外计算量是 staggering .
消除旋转将允许使用 InstancedMesh 获得更多实例。
我将让您了解我当前的应用程序是什么,这样您就会明白为什么这个讨论是相关的。我想通过实例化立方体来渲染 128^3 体素空间,因为它是渲染体素更直接的方法之一。请注意,如果所有这些体素都已设置,那将是 210 万个立方体。对于变换矩阵,每个实例 64 字节,即每帧消耗约 134MB 的总线带宽。那根本行不通。
因此,当与用于实例化的转换相关的数据量过多或操作该数据的计算开销过多时,您将不得不回退到更底层的 InstancedBufferGeometry 方法并开始使用着色器。
这是关于 InstancedMesh 的另一件事。它允许您避免接触着色器。
对于体素,有大量技术可以将性能恢复到非常易于管理的位置,可能理想的是greedy voxel meshing (sweet animation!)但即使没有那么复杂,很明显可以将流式传输数据的带宽成本降低 20 倍,仅使用 3 字节数据来编码每个体素的位置,而不是使用完整的 64 字节矩阵来实现。您只需要像我一样使用 InstancedBufferGeometry 即可。

关于three.js - ThreeJS中的InstancedBufferGeometry和InstancedMesh有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60066577/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com