以下是他们的文件:
InstancedMesh:https://thirdjs.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))。几何形状不包含颜色,但材料包含颜色。
从上面的示例中,我看到他们将颜色属性放入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 ) );
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果我想用不同颜色渲染 1000 个正方形平面并独立移动,我应该使用InstancedMeshor 吗InstancedBufferGeometry?为什么?它们可以一起使用吗?
好吧,我已经完成了 @pailhead 的 Medium 文章三部曲,顺便说一句,感谢您的演练!
以下是我目前对使用 InstancedMesh 的良好情况的理解:
如果您的部分或全部实例会经常更改,并且您的实例少于约 50K,并且实例之间的差异可以通过 TRS 变换(或颜色)来描述,那么 InstancedMesh 应该非常适合您。
如果您的大多数实例都是静态的,并且您一次只更新几个实例,那么您的实例数量可能是无限的(直到达到 GPU 渲染瓶颈或 VRAM 大小)。
我通过观察几个示例的行为以及通过扩大实例计数得出了这些值:https ://codesandbox.io/s/r3f-instanced-colors-8fo01
我认为这个 R3F 示例涉及足够的“额外内容”,可以引入足够的开销,以更接近真实的应用程序。
通过查看 Chrome 中的性能选项卡,我发现您将大部分时间花在主 CPU 线程上(记住,可能可以将这项工作分叉给工作线程)处理 updateMatrix 调用和像这样的东西。基本上,如果您尝试在主线程上旋转超过 50,000 个对象中的每一个,您的应用程序将无法在典型系统上很好地运行,您的 CPU 需要使用大量的三角函数来计算每一帧!由于 InstancedMesh 接口,这将极大地限制 CPU,它使您可以自由地为每个实例分配变换(以及可选的颜色)。
如果您确实需要在每个帧中变换每个实例,您可能需要考虑是否可以将变换计算卸载到 GPU 本身,执行此操作的标准方法是使用顶点着色器。与一个 CPU 线程相比,使用顶点着色器可以完成的额外计算量是惊人的。
消除旋转将允许使用 InstancedMesh 实现更多实例。
我将让您了解我当前的应用程序是什么,以便您了解为什么此讨论是相关的。我想通过实例化立方体来渲染 128^3 体素空间,因为它是渲染体素的更直接的方法之一。请注意,如果所有这些体素均已设置,则仅剩不到 210 万个立方体。对于每个变换矩阵实例 64 字节,每帧消耗约 134MB 的总线带宽。那根本不行。
因此,当实例化转换涉及的数据量太大或者操作该数据的计算开销太大时,您将不得不退回到更底层的 InstancedBufferGeometry 方法并开始使用着色器。
这是 InstancedMesh 的另一件事。它可以让您避免接触着色器。
对于体素,有大量的技术可以将性能恢复到非常易于管理的水平,理想的可能是贪婪的体素网格划分(可爱的动画!),但即使没有那么复杂,显然也有可能提高流媒体的带宽成本该数据减少了 20 倍,仅使用 3 字节数据来编码每个体素的位置,而不是使用完整的 64 字节矩阵。您只需要像我一样使用 InstancedBufferGeometry 即可做到这一点。
| 归档时间: |
|
| 查看次数: |
3527 次 |
| 最近记录: |