如何快速更新大的BufferGeometry?
Posted
技术标签:
【中文标题】如何快速更新大的BufferGeometry?【英文标题】:How to quickly update a large BufferGeometry? 【发布时间】:2013-06-28 22:41:29 【问题描述】:我正在使用 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,
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;
如果我移动了一个立方体,在我这样做之前它似乎不会被移动:
geometry.attributes.position.needsUpdate = true;
这会导致 FPS 在更新时下降。还有其他方法可以做到这一点吗?当我只更改一个立方体(12 个三角形/36 个顶点)时,似乎有点不必要。虽然它可能是 - 我还没有检查 needsUpdate
实际做了什么。猜测它会将数组再次发送到着色器。
我在想我可以将几何体拆分为单独的更小的 BufferGeometries,但我不确定这是否有助于整体性能。据我了解,更多的几何图形 = 更少的 FPS。
如果有人对我将如何做到这一点有任何想法,将不胜感激! :) 除了更新问题,BufferGeometry 似乎正是我所需要的。谢谢!
【问题讨论】:
【参考方案1】:在更新其中的几个顶点时,我遇到了一个非常大的BufferGeometry
的问题。
一种解决方案是使用_gl.bufferSubData
而不是_gl.bufferData
来仅更新缓冲区的一部分。 (three.js 仅使用 _gl.bufferData
)。
所以如果你更新你会做的职位:
// Create a view of the data to update from index offsetSub to offsetSubEnd
var view = geometry.attributes.position.array.subarray(offsetSub, offsetSubEnd);
// Bind the buffer for positions (get the gl context with webglrenderer)
_gl.bindBuffer(_gl.ARRAY_BUFFER, geometry.attributes.position.buffer);
// Insert the new values at good index in gpu buffer (offsetGeometry is in byte)
_gl.bufferSubData(_gl.ARRAY_BUFFER, offsetGeometry,view);
请注意,与_gl.bufferData
相比,如果您更改大部分缓冲区顶点,此解决方案可能会更慢。
【讨论】:
【参考方案2】:截至r71
threejs 支持bufferSubData
。
使用DynamicBufferAttribute
,(或正确设置updateRange
)
var positionAttr = geometry.attributes.position
// if not using DynamicBufferAttribute initialize updateRange:
// positionAttr.updateRange = ;
positionAttr.updateRange.offset = 0; // where to start updating
positionAttr.updateRange.count = 1; // how many vertices to update
positionAttr.needsUpdate = true;
【讨论】:
不确定是哪个版本改的,但截至r81
,这已被合并到BufferAttribute
。以上是关于如何快速更新大的BufferGeometry?的主要内容,如果未能解决你的问题,请参考以下文章
THREE.OBJLoader - 缩放网格和BufferGeometry顶点
绘制不断变色的台体,BufferGeometry和ShaderMaterial的黄金组合(three.js实战5)
如何在 STL 加载的 BufferGeometry 中平滑网格三角形
三维空间中绘制点线面UV贴图,万能的BufferGeometry(three.js实战4)