正确的 OpenGL 矩阵格式?

发布于 2024-10-06 07:33:31 字数 326 浏览 3 评论 0原文

我的问题很简单:投影和模型视图矩阵的正确格式是什么?

有人告诉我,以下示例矩阵是转置的,并且不是像 OpenGL 矩阵那样构建的。

ModelView Matrix
{(1, 0, 0, 0)
(0, 0.7071068, 0.7071068, 0)
(0, -0.7071068, 0.7071068, 0)
(0, -141.4214, -141.4214, 1)}

Projection Matrix
{(1.931371, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.0002, -1)
(0, 0, -2.0002, 0)}

My question simply is: what is the correct format for the Projection and ModelView matrix?

I've been told that the following example matrices are transposed and are not built like OpenGL matrices should be.

ModelView Matrix
{(1, 0, 0, 0)
(0, 0.7071068, 0.7071068, 0)
(0, -0.7071068, 0.7071068, 0)
(0, -141.4214, -141.4214, 1)}

Projection Matrix
{(1.931371, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.0002, -1)
(0, 0, -2.0002, 0)}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

傲性难收 2024-10-13 07:33:31

编辑:这个答案非常需要更新。也就是说,没有考虑着色器。

正如 @gman 在评论中指出的那样,是使用行优先还是列优先取决于您如何进行数学计算。您可以选择其中之一(如果您不认为这令人困惑,甚至可以在不同时间选择两者),只要它们与您的坐标系和操作顺序匹配即可。

我将留下这个答案作为社区维基,以防有人有时间并且愿意更新它。


OpenGL 将矩阵指定为按列主顺序列出的一维数组,即元素按如下顺序排序:

m0 m4 m8  m12
m1 m5 m9  m13
m2 m6 m10 m14
m3 m7 m11 m15

因此,如果您以这种方式初始化数组,在 C 或几乎任何其他语言中,生成的矩阵看起来需要转置,因为 C 代码首先从左到右读取,然后从上到下读取(换句话说,就像它处于行优先状态一样) order):

int mat[16] = {
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 10, 11,
    12, 13, 14, 15,
}

顺便说一下,OpenGL既有 glLoadTransposeMatrixglMultTransposeMatrix,您可以使用它来代替 glLoadMatrix 和 glMultMatrix,所以这应该不是问题。

Edit: this answer is in serious need of an update. Namely, there is no consideration about shaders.

As @gman points out in the comments, whether to use row-major or column-major depends on how you do your math. You may choose one or the other (or even both at different times if you don't think that's confusing) just as long as they match your coordinate systems and order of operations.

I'm leaving this answer as community wiki in case someone has the time and will to update it.


OpenGL specifies matrices as a one-dimensional array listed in column-major order, ie with elements ordered like this:

m0 m4 m8  m12
m1 m5 m9  m13
m2 m6 m10 m14
m3 m7 m11 m15

So if you initialize an array this way, in C or pretty much any other language, the resulting matrix will look like it needs transposing, because C code reads left-to-right first and then top-to-bottom (in other words, like if it were in row-major order):

int mat[16] = {
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 10, 11,
    12, 13, 14, 15,
}

By the way, OpenGL has both glLoadTransposeMatrix and glMultTransposeMatrix, which you can use instead of glLoadMatrix and glMultMatrix, so this shouldn't be a problem.

白云悠悠 2024-10-13 07:33:31

您可以使用任何您喜欢的表示法,只要与矩阵运算的顺序一致即可。引用自 https://www.opengl.org/archives/resources/faq /technical/transformations.htm

9.005 OpenGL 矩阵是列优先还是行优先?

出于编程目的,OpenGL 矩阵是 16 值数组,其中
基向量在内存中连续排列。翻译
分量占据 16 元素中的第 13、14 和 15 个元素
矩阵,其中索引编号为 1 到 16,如中所述
OpenGL 2.1 规范第 2.11.2 节。

列优先与行优先纯粹是一种符号约定。笔记
与列主矩阵的后乘产生相同的结果
结果与行优先矩阵预乘。 OpenGL
规范和 OpenGL 参考手册都使用列优先
符号。您可以使用任何符号,只要明确说明即可。

即在着色器中,您可以将转换矩阵作为按排序的浮点数组加载到统一中,并预乘顶点来转换它:

gl_Position = Proj * View * Model * vPosition;

或加载与浮点数组相同的矩阵按后乘排序以达到相同的效果:

gl_Position = vPosition * Model * View * Proj;

通过转置矩阵,您可以有效地将其转换为以相反的表示法存储,这就是为什么OpenGL可以选择输入矩阵时进行转置。

You can use whichever notation you like, as long as you're consistent with the ordering of matrix operations. Quoting from https://www.opengl.org/archives/resources/faq/technical/transformations.htm:

9.005 Are OpenGL matrices column-major or row-major?

For programming purposes, OpenGL matrices are 16-value arrays with
base vectors laid out contiguously in memory. The translation
components occupy the 13th, 14th, and 15th elements of the 16-element
matrix, where indices are numbered from 1 to 16 as described in
section 2.11.2 of the OpenGL 2.1 Specification.

Column-major versus row-major is purely a notational convention. Note
that post-multiplying with column-major matrices produces the same
result as pre-multiplying with row-major matrices. The OpenGL
Specification and the OpenGL Reference Manual both use column-major
notation. You can use any notation, as long as it's clearly stated.

i.e. in a shader you can load transformation matrices as float arrays ordered by columns into a uniform and pre-multiply a vertex to transform it:

gl_Position = Proj * View * Model * vPosition;

or load the same matrices as float arrays ordered by rows and post-multiply to achieve the same effect:

gl_Position = vPosition * Model * View * Proj;

By transposing a matrix you effectively transform it to be stored in the opposite notation, which is why OpenGL has options to transpose matrices as they are inputted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文