【问题标题】:How to multiply a 4x4 Matrix with a vector-array of arbitrary length?如何将 4x4 矩阵与任意长度的向量数组相乘?
【发布时间】:2015-05-05 18:18:34
【问题描述】:

在 webgl 中编写特定场景时,转换对象的通常过程是定义原始 顶点位置数据并将其传递给顶点着色器,其中 顶点 em> 与 矩阵 相乘,矩阵包含有关透视、平移、旋转和缩放的信息,因此相应的顶点着色器代码(例如 - 看起来像这样:

gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0);

modelviewMatrix 本身就是 viewMatrixmodelMatrix 相乘的结果,这也是连续矩阵操作的结果平移、旋转和缩放。

我现在想知道的是,乘法链中的最后一个环节是如何工作的 - mat4 与任意长度的向量数组的乘法。

someMatrix * vec4(vertexPosition, 1.0);

那是因为我在 webgl 编辑器上编写,我希望能够保存创建的 和转换的 3D 对象的顶点位置数据,而无需添加有关矩阵转换的信息但是作为原始位置数据,就像{x, y, z, x, y, z, x, y, z, etc.}一样,就像原始的顶点数组一样。

作为一个基本示例,假设我们有一个简单三角形的以下顶点:

var vertices = [0.0, 1.0, 0.0,  -1.0, -1.0, 0.0,  1.0, -1.0, 0.0];

然后我创建一个 mat4 并通过[2, 0, 0]翻译它。

然后我需要的函数会将这个翻译后的 mat4vertices 数组作为参数,将两者相乘并返回一个 translated 数组像这样的顶点:

var translatedVertices = [2.0, 1.0, 0.0,  1.0, -1.0, 0.0,  3.0, -1.0, 0.0];

似乎很明显,要将 4x4 矩阵与向量数组相乘,必须为其添加第四个值,因此第一步应该是拆分原始 vec3 数组并插入对于每个三元组的值,一个额外的 1.0,使其成为 vec4 数组,[x, y, z] --> [x, y, z, 1],但除此之外,我完全不知道这个 JavaScript 函数应该是什么样子。

【问题讨论】:

  • 仅供参考:您可以使您的着色器具有attribute vec4 vertexPosition;,但每个顶点仍只能使用gl.vertexAttribPointer(vertexPositionLoc, 3, gl.FLOAT, false, 0, 0); 传递3 个值。 w 如果没有为属性提供,则默认为 1,因此此 someMatrix * vec4(vertexPosition, 1.0); 可以简化为 someMatrix * vertexPosition;
  • 哇,我一直认为,属性的数据类型必须等于相应缓冲区的item size,记为gl.vertexAttribPointer 的第二个参数。 - 不错的小技巧!谢谢你,gman!

标签: javascript webgl


【解决方案1】:

当你说

someMatrix * vec4(vertexPosition, 1.0);

someMatrix 是一个 4x4 矩阵,vertexPosition 始终是一个 3x1 矩阵,通过添加 1.0 转换为 4x1 矩阵。所以一个 4x4 矩阵乘以一个 4x1 矩阵将再次产生一个有效的 4x1 矩阵(即gl_Position)。请注意,4x1 矩阵是vec4

因此,您永远不会与“任意”长度的向量相乘。当您向下传递数据(即您的 vertices 变量)时,系统会将它们分解为三元组,添加 1.0 并执行 4x4 乘以 4x1 的乘法。

【讨论】:

  • 非常感谢,gaitat!为什么事情本来可以这么简单却把事情复杂化... ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多