【问题标题】:How can I add faces to an indexed THREE.BufferGeometry?如何将面添加到索引的 THREE.BufferGeometry?
【发布时间】:2020-12-01 08:05:23
【问题描述】:

假设我从名为 oldGeomTHREE.Geometry 生成了一个 THREE.BufferGeometry,如下所示:

// using WebGLRenderer
var geometry = new THREE.BufferGeometry();
var indices = new Uint16Array(oldGeom.vertices.length);
var vertices = new Float32Array(oldGeom.vertices.length * 3);
for (var i = 0; i < oldGeom.vertices.length; i++) {
    indices[i] = i;
    vertices[i * 3 + 0] = oldGeom.vertices[i].x;
    vertices[i * 3 + 1] = oldGeom.vertices[i].y;
    vertices[i * 3 + 2] = oldGeom.vertices[i].z;
}
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));

希望我有索引权。此时,如何使用索引添加人脸?我打算遍历oldGeom 的面孔以将它们全部添加到此处,但我找不到任何有关此的文档。谢谢!

类似于this question,但具有索引几何。

【问题讨论】:

  • 您使用 BufferGeometry 有什么原因吗?当您受到严重的性能限制并且需要挤出一些额外的优化时,通常应该保留它,即使那样您最好知道自己在做什么。除此之外,我不清楚这个问题。您是否在问如何在 BufferGeometry 上重新创建原始几何图形的三角形?或者您是在问如何将全新的面添加到 oldGeom 中不存在的 BufferGeometry?顺便说一句,BufferGeometry 有一个从 Geometry 克隆的便捷方法,那么为什么不使用它呢?
  • 感谢您的评论!是的——我正在使用 BufferGeometry,以便我可以根据 WestLangley 对this question 的建议,通过利用.setDrawRange(...) 动态添加新顶点。这也是为什么我不能使用.fromGeometry(...) 来构建这个 BufferGeometry 的原因——我希望缓冲区大于原始几何的大小(抱歉,我没有用更大的缓冲区编写上面的代码!)跨度>
  • 无论如何,重新表述我的问题:我只是想知道有人会如何在索引的 BufferGeometry 中定义一个三角形。是否有一些数组可以填充顶点索引来定义我的脸?
  • 感谢@JCD,如果我能澄清更多,请告诉我
  • 好的,我一直在阅读源代码,我要问这两个非常愚蠢的问题——索引是面索引还是顶点索引?并且这些面是由位置属性中的相邻三重奏定义的吗?

标签: javascript three.js


【解决方案1】:

来自the documentation for BufferGeometry:

索引(itemSize:3)

允许在多个三角形中重复使用顶点;这被称为使用“索引三角形”,其工作方式与几何中的工作方式大致相同:每个三角形都与三个顶点的索引相关联。因此,此属性存储每个三角形面的每个顶点的索引。如果未设置此属性,则渲染器假定每三个连续位置代表一个三角形。

“索引三角形”的工作方式是“位置”是一个数字数组,每组连续的 3 个数字代表一个顶点(x、y、z)。 “索引”是一个数字数组,其中每个连续的 3 个数字集合代表一个面,通过引用“位置”数组中顶点的索引

你可能有一个这样的顶点数组:

var vertices = [0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0];

您可以将此数组视为一组 XYZ 坐标,如下所示:

var vertices = [
    0, 0, 0, // vertex index 0
    1, 0, 0, // vertex index 1
    1, 1, 0, // vertex index 2
    0, 1, 0  // vertex index 3
];

现在如果你有一个这样的索引数组:

var indices = [0, 1, 2, 1, 2, 3];

它代表两个三角形:

var indices = [
    0, 1, 2, // face with vertices at indices 0, 1, 2
    1, 2, 3  // face with vertices at indices 1, 2, 3
];

所以三角形 #1 在 XYZ (0, 0, 0), (1, 0, 0), (1, 1, 0) 有顶点,而三角形 #2 在 XYZ (1, 0, 0) 有顶点, (1, 1, 0), (0, 1, 0)。

另一方面,您可以不使用使用索引来定义顶点。索引的强大之处在于它可以让您重用数组中定义的顶点,而不是每次出现在三角形中时都冗余地列出它们。如果你有一个数组,vertices,那么很简单,数组中的每组 9 个数字都是一个三角形(三组连续的顶点,每组有三个连续的 XYZ 值)。

回到你原来的问题,如果你想在 BufferedGeometry 中添加三角形,我看到两个基本选项:

  1. 将三角形添加到原始oldGeom 对象,然后对其进行转换。将三角形添加到 Geometry 比 BufferGeometry 容易得多。请记住,BufferGeometry 的全部意义在于它不应该改变!您还可以利用.fromGeometry(),因为新面孔已经在oldGeom 中定义。
  2. 创建一个大于原始索引所需的indices 数组并在那里手动定义三角形。如果您要定义顶点数组中不存在的新顶点,那么您也必须在其中添加它们。好痛啊。

【讨论】:

  • 谢谢!绝对痛苦。可能会尝试重新考虑整个事情。
猜你喜欢
  • 2016-03-12
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 2016-07-23
相关资源
最近更新 更多