我正在使用BufferGeometry绘制数千个构成地形的立方体,但是如果我需要更改其中一个立方体的位置,则很难找到如何更新几何体.例如,我有这个代码来初始化我的几何:(我正在测试更新版本的
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,color: { itemSize: 3,numItems: triangles * 3 * 3 } } positions = geometry.attributes.position.array; normals = geometry.attributes.normal.array; colors = geometry.attributes.color.array;
如果我移动一个立方体,它将不会被移动,直到我这样做:
geometry.attributes.position.needsUpdate = true;
这会导致FPS在更新时掉线.还有另外一种方法吗?当我只改变一个立方体(12个三角形/ 36个顶点)时,似乎有点不必要了.虽然它可能 – 我还没有检查needUpdate实际上做了什么.猜测它再次将数组发送到着色器.
我在想我可以将几何体分成单独的较小的BufferGeometries,但我不确定这是否有助于整体性能.据我所知,更多的几何形状=更少的FPS.
如果有人有任何想法我将如何做到这一点,将不胜感激! :)除了更新问题,BufferGeometry似乎正是我需要的.谢谢!
解决方法
当我更新一些顶点时,我遇到了一个非常大的BufferGeometry问题.
解决方案是使用_gl.bufferSubData而不是_gl.bufferData来仅更新缓冲区的一部分. (三个js仅使用_gl.bufferData).
因此,如果您更新职位,您将执行以下操作:
//创建要从索引offsetSub更新到offsetSubEnd的数据视图
var view = geometry.attributes.position.array.subarray(offsetSub,offsetSubEnd);
//将缓冲区绑定到位置(使用webglrenderer获取gl上下文)
_gl.bindBuffer(_gl.ARRAY_BUFFER,geometry.attributes.position.buffer);
//在gpu缓冲区中以良好索引插入新值(offsetGeometry以字节为单位)
_gl.bufferSubData(_gl.ARRAY_BUFFER,offsetGeometry,view);
请注意,与_gl.bufferData相比,如果更改大部分缓冲区顶点,此解决方案可能会更慢.