Three.js 中的 BoxBufferGeometry 与 BoxGeometry 有啥区别?

Posted

技术标签:

【中文标题】Three.js 中的 BoxBufferGeometry 与 BoxGeometry 有啥区别?【英文标题】:What is difference between BoxBufferGeometry vs BoxGeometry in Three.js?Three.js 中的 BoxBufferGeometry 与 BoxGeometry 有什么区别? 【发布时间】:2018-10-02 01:02:40 【问题描述】:

我正在学习 Three.js。我找不到关于 BoxBufferGeometry 与 BoxGeometry 之间区别的正确答案。帮帮我。

【问题讨论】:

【参考方案1】:

[Primitive]Geometry 类对所有 JS 几何类的操作友好,内存不友好。

这意味着定义此几何图形的每条数据都存储为某个类的实例 (Vector3,Vector2,Face3) 等。这些带有方便的方法,因此您可以点一个顶点使用其他向量,平移顶点,修改 uvs,修改法线等。但它在内存和性能方面有开销(创建所有这些实例,存储它们)。

[Primitive]BufferGeometry 类是性能友好的几何类,它们依赖于类型化数组以 WebGL 友好的格式存储数据。

这意味着顶点不是Vector3s 的数组,而是类型化数组:

Array[v0,v1... vN]
vs:
Float32Array[v0x,v0y,v0z,v1x,v1y,v1z... vNx,vNy,vNz] 

它们的存储效率更高,但更难操作。

如果你想修改一个顶点:

Geometry

//with Geometry you just get vertex 5 and have access to it's x...
//AND the methods of the class -> Vector3.add(Vector3)
myGeom.vertices[5].add(new THREE.Vector3(1,2,3))

BufferGeometry

//xyz are just numbers, so with a stride of 3
//we select x , and  then the next two for y and z
//we have to know that the 15th number in this array is x of vertex 5...
const stride = 3
const index = 5
let offset = index * stride
myGeom.attributes.position.array[offset++] += 1 
myGeom.attributes.position.array[offset++] += 2 
myGeom.attributes.position.array[offset  ] += 3 

但是

THREE.BufferAttribute 确实有几种方法可以从该数组中写入和读取内容。它仍然更加冗长:

//add x: 1 y: 2 z: 3 to 5th vertex

const index = 5
const attribute = myGeometry.attributes.position
const v3add = new THREE.Vector3(1,2,3)

attribute.setXYZ( 
  index, 
  attribute.getX(index) + v3add.x,
  attribute.getY(index) + v3add.y,
  attribute.getZ(index) + v3add.z
)

【讨论】:

虽然更容易阅读,但我倾向于说BufferGeometry 更改示例是不正确的。 1) 标准[Primitive]BufferGeometry 对象的顶点存储在myGeom.attributes.position 中。除非您为自定义着色器添加自定义属性,否则没有 vertices 属性。 2) 您仍然可以通过索引获取和设置值,只是有点冗长。 var pos = myGeom.attributes.position; pos.setXYZ(5, pos.getX(5) + 1, pos.getY(5) + 2, pos.getZ(5) + 3);. 这个答案有多个错误,@pailhead 更清楚。 请编辑一下,这主要是伪代码,add(1,2,3) 也没有意义。 这个想法是从概念上解释差异,而不是给出确切的名称和属性。这里的重要概念是数组本身,而不是它所在的位置,但我已经编辑了答案。【参考方案2】:

@Pailhead 的回答是正确的。如果您需要以某种方式修改盒子.. 通过移动它的顶点或更改 texcoords,操作 BoxGeometry 会更容易,但 BoxBufferGeometry 的渲染效率更高。您可以使用 .fromGeometry 和 .fromBufferGeometry 在类型之间进行转换。

【讨论】:

这确实应该是对 pailhead 答案的评论,而不是单独的答案。

以上是关于Three.js 中的 BoxBufferGeometry 与 BoxGeometry 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Three.js 中的 BoxBufferGeometry 与 BoxGeometry 有啥区别?

为啥 Three.js 中的 ColladaLoader.js 无法加载我的文件?

three.js 中的工具提示

动画 GIF 作为 THREE.js 中的纹理

Three.js 中的操纵杆、游戏手柄或 3D 鼠标支持

three.js 中的分层纹理