如何快速更新大型BufferGeometry? [英] How to quickly update a large BufferGeometry?
问题描述
我正在使用BufferGeometry来绘制构成地形的数千个立方体,但是如果我需要更改其中一个立方体的位置,则很难找到如何更新几何体。例如,我有这个代码来初始化我的几何:(我正在测试更新版本的这个例子)
I'm using a BufferGeometry to draw thousands of cubes which makes up the terrain, but having a hard time finding out how to update the geometry if I need to change the position of one of the cubes. For example, I have this code to initialize my geometry: (I'm doing my testing on an updated version of this example)
// 12 triangles per cube (6 quads)
var triangles = 12 * 150000;
var geometry = new THREE.BufferGeometry();
geometry.attributes = {
position: {
itemSize: 3,
array: new Float32Array( triangles * 3 * 3 ),
numItems: triangles * 3 * 3
},
normal: {
itemSize: 3,
array: new Float32Array( triangles * 3 * 3 ),
numItems: triangles * 3 * 3
},
color: {
itemSize: 3,
array: new Float32Array( triangles * 3 * 3 ),
numItems: triangles * 3 * 3
}
}
positions = geometry.attributes.position.array;
normals = geometry.attributes.normal.array;
colors = geometry.attributes.color.array;
如果我移动一个立方体,它将不会被移动,直到我这样做:
If I move a cube, it won't appear to be moved until I do:
geometry.attributes.position.needsUpdate = true;
这会导致FPS在更新时丢失。还有另外一种方法吗?当我只改变一个立方体(12个三角形/ 36个顶点)时,似乎有点不必要了。虽然它可能 - 我还没有检查 needsUpdate
实际上是什么。猜测它再次将数组发送到着色器。
This causes the FPS to drop while it's being updated. Is there another way I could do this? Seems a bit unnecessary when I'm only changing one cube (12 triangles/36 vertices). Although it might be - I haven't checked what needsUpdate
actually does. Guessing it sends the array to the shader again.
我以为我可以将几何体拆分成单独的较小的BufferGeometries但是我不确定这是否有助于整体性能。根据我的理解,更多的几何形状=更少的FPS。
I was thinking I could split the geometry into separate smaller BufferGeometries but I'm not sure if that would help the performance overall. From what I understand, more geometries = less FPS.
如果有人有任何想法我会怎么做,我们将不胜感激! :)除了更新问题,BufferGeometry似乎正是我需要的。谢谢!
If anyone has any ideas how I would do this, it would be appreciated! :) Besides the updating issue, BufferGeometry seems to be exactly what I need. Thanks!
推荐答案
在更新其中的几个顶点时,我遇到了一个非常大的BufferGeometry问题。
I had the same problem with a very large BufferGeometry when updating a few vertices in it.
解决方案是使用_gl.bufferSubData而不是_gl.bufferData来更新缓冲区的一部分。 (三个js仅使用_gl.bufferData)。
A solution is to use _gl.bufferSubData instead of _gl.bufferData to update just a part of the buffer. (Three js uses only _gl.bufferData).
因此,如果你更新你将要做的头寸:
So if you update the positions you will do:
//创建要从索引offsetSub更新到offsetSubEnd的数据视图
// Create a view of the data to update from index offsetSub to offsetSubEnd
var view = geometry.attributes.position.array.subarray(offsetSub ,offsetSubEnd);
//将缓冲区绑定到位置(使用webglrenderer获取gl上下文)
// Bind the buffer for positions (get the gl context with webglrenderer)
_gl.bindBuffer(_gl.ARRAY_BUFFER,geometry.attributes.position.buffer);
//在gpu缓冲区中以良好的索引插入新值(offsetGeometry以字节为单位)
// Insert the new values at good index in gpu buffer (offsetGeometry is in byte)
_gl.bufferSubData(_gl.ARRAY_BUFFER,offsetGeometry,查看);
请注意,如果更改大部分缓冲区顶点与_gl.bufferData相比,此解决方案可能会更慢。
Note that this solution can be slower if you change a large part of the buffer vertices compared to _gl.bufferData.
这篇关于如何快速更新大型BufferGeometry?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!