Three.js - PlaneBufferGeometry是什么?

23

PlaneBufferGeometry是什么,它与PlaneGeometry有何不同?(r69)

2个回答

28

PlaneBufferGeometry 是一个低内存的备选方案,替代了 PlaneGeometry。这两个对象本身有很多不同之处。例如,在PlaneBufferGeometry 中,顶点位于PlaneBufferGeometry.attributes.position 而不是PlaneGeometry.vertices

你可以在浏览器控制台中快速查看以了解更多差异,但就我所理解的而言,由于顶点通常是相互间距离相等(XY)的,只需要给出高度(Z)即可定位顶点。


即使使用PlaneGeometry或PlaneBufferGeometry已经给出了x,y坐标,它们仍然是每个顶点数据表示的一部分,并且仍然可以被修改。 - Elias Hasle

10
主要区别在于 GeometryBufferGeometry
Geometry 是一种“用户友好”的面向对象的数据结构,而 BufferGeometry 是一种将数据映射到着色器程序中更直接的数据结构。BufferGeometry 更快并且需要更少的内存,但 Geometry 在某些方面更灵活,某些操作可以更轻松地完成。
我很少使用 Geometry,因为我发现在大多数情况下 BufferGeometry 可以胜任。了解和使用着色器实际使用的数据结构非常有用。
在 PlaneBufferGeometry 的情况下,您可以这样访问顶点位置:
let pos = geometry.getAttribute("position");
let pa = pos.array;

然后像这样设置z值:
var hVerts = geometry.heightSegments + 1;
var wVerts = geometry.widthSegments + 1;
for (let j = 0; j < hVerts; j++) {
    for (let i = 0; i < wVerts; i++) {
                            //+0 is x, +1 is y.
        pa[3*(j*wVerts+i)+2] = Math.random();
    }
}
pos.needsUpdate = true;
geometry.computeVertexNormals();

随机性只是一个例子。如果你在内部循环中 let x = pa[3*(j*wVerts+i)];let y = pa[3*(j*wVerts+i)+1];,你也可以绘制一个关于x和y的函数(另一个例子)。对于PlaneBufferGeometry的性能优化,建议在外部循环中使用let y = (0.5-j/(hVerts-1))*geometry.height

如果您的材质使用法线并且您没有通过解析计算出更精确的法线,则建议使用geometry.computeVertexNormals();。如果您不提供或计算法线,则材质将使用默认平面法线,所有法线都指向原始平面的外侧。

请注意,沿某个维度的顶点数比同一维度的线段数多一个。

还要注意的是(与直觉相反),y值与j索引相反:vertices.push( x, - y, 0 );source


1
widthSegments + 1 中,+1 是必要的吗?这会跳过第一行,对吗? - dansch
假设您指的是以下代码行: pa[3*(j*(geometry.widthSegments+1)+i)+2] = Math.random(); 当j为0时,将迭代第一行。 - Elias Hasle
1
不错且实用!或许最好加上为什么在循环和计算中使用+1逻辑的解释。要生成N个线段,需要N+1个顶点。因此,实际顶点数总是比线段数多1个。 - user173399

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接