OpenGL 坐标系是右手坐标系还是左手坐标系?

发布于 2024-10-20 02:20:48 字数 193 浏览 3 评论 0原文

假设我在 OpenGL ES 2.0 程序上为 modelViewTransformation Matrix 使用单位矩阵。本例中的坐标系是规范的 OpenGL 坐标系,从 (-1,-1,-1) 延伸到 (1,1,1)。

这个坐标系是右手坐标系还是左手坐标系?

更广泛的问题:是否有 OpenGL 文档可以列出 API 遵循的所有数学约定?

Say I am using an Identity Matrix for my modelViewTransformation Matrix on an OpenGL ES 2.0 program. The Co-ordinate system in this case is the canonical OpenGL co-ordinate system which extends from (-1,-1,-1) to (1,1,1).

Is this coordinate system right-handed or left-handed?

A broader question: Is there a document with OpenGL which can list all the mathematical conventions followed by the API?

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

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

发布评论

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

评论(4

小…楫夜泊 2024-10-27 02:20:48

永远记住! OpenGL 只知道标准化显示坐标 (NDC),而且它是LEFT_HANDED

OpenGL是右旋的错觉是因为在固定管线中,固定函数是右旋的,如glOrtho(...)、glFrustrum(...)。所有这些函数在可编程流水线时代都已被弃用。

OpenGL 并不关心您在中间矩阵处理中使用什么手坐标系。如果需要,您可以使用任何轴坐标系,只要将其转换为 NDC 即可。

忘记相机吧!

因为我们的屏幕是一个2D平面。想象一下,您的视口是一个黄色橡胶方块。将该正方形的四个角固定到 NDC 的 -Z 侧,如下所示:

A 正交立方体的线框图像角顶点是 (X, Y, Z) 中 -1 和 +1 的所有组合,其中心有一个可见的原点/轴标记,+X 指向右侧,+Y 指向上方,+Z 指向远离观察者的方向,面向观察者的 -Z 立方体一侧涂为黄色以突出显示。

NDC 空间中 -Z 轴上的所有顶点都位于并定义黄色橡胶方块上。然后,黄色橡胶平面被拉伸以适合并显示在您的实际屏幕上。

ALWAYS REMEMBER!! OpenGL only knows about Normalized Display Coordinates (NDC), and it is LEFT_HANDED!

The illusion OpenGL is right-handed is because in the fixed pipeline, the fixed functions are right-handed, like glOrtho(...), glFrustrum(...). All these functions have been deprecated in programmable-pipeline times.

OpenGL doesn`t care what handed coordinate system you use for intermediate matrix processes. You can use any axis coordinate system if you want, as long as you translate that to NDC.

Forget about the camera!

Because our screen is a 2D plane. Imagine this, your viewport is a yellow rubber square. Pin the four corners of that square to the -Z side of the NDC, something like this:

A wireframe image of an orthonormal cube with corner vertices being all combinations of -1 and +1 in (X, Y, Z), with a visible origin/axes marker in its center that has +X pointing right, +Y pointing up, and +Z pointing away from the viewer, with the -Z cube side facing the viewer colored yellow to highlight it.

All vertices in the -Z axis in NDC space are on, and define, the yellow rubber square. The yellow rubber plane is then stretched to be fitted to, and shown on, your actual screen.

别想她 2024-10-27 02:20:48

规范视图体积(又名标准化设备坐标)是左手坐标。 ,这很容易测试,

float points[] = { -1,  1,  -0.5,
                   -1, -1,  -0.5,
                    1, -1,  -0.5,

                    1,  1,   0.5,
                   -1, -1,   0.5,
                    1, -1,   0.5 };

通过传递单位矩阵并绘制 2 个三角形并查看结果(使用 glEnable(GL_DEPTH_TEST))

所以你的顶点着色器将如下所示:

uniform mat4 mvp_mat;

// Incoming per vertex... position (fills in 1 for w if from vec3 buf)
layout (location = 0) in vec4 v_vertex;


void main(void) 
{ 
    // multiplying by identity doesn't transform the geometry
    gl_Position = mvp_mat * v_vertex;
}

或者你甚至可以像这样更简单地测试它,因为单位矩阵显然

layout (location = 0) in vec4 v_vertex;

void main(void) 
{
    //no transformation, no confusion, just straight to OpenGL
    gl_Position = v_vertex;
}

,您必须使三角形的颜色不同,以便您可以看到它们如何重叠。

另请参阅这篇文章和其中我的评论/问题:
plus.google.com/114825651948330685771/posts/AmnfvYssvSe

我不知道所有不正确的信息来自互联网甚至教科书。如果您正在谈论用于确定正面的三角形缠绕(默认情况下 CCW = 右手),则 OpenGL 默认情况下仅是右手。世界空间、物体空间和眼睛空间对于OpenGL来说并不存在,只存在于图形程序员之中。 OpenGL 只是获取点,剪切规范视图体积 [-1, -1, -1] x [1, 1, 1] 之外的任何内容,并将它们转换为屏幕空间/窗口坐标,默认情况下为 [0, w) x [ 0, h) x [0, 1]。如果启用深度测试,则默认行为是左手,向下看 +z。

有多种方法可以解释 OpenGL 的左撇子特性。大多数人在矩阵中处理​​它(尽管他们没有意识到)。我认为您还可以使用 glDepthFunc 更改它并将其设置为 GL_GREATER。

http://www.opengl.org/sdk/docs/man3/ xhtml/glDepthFunc.xml

进一步证明它是左撇子在这里
http://www.opengl.org/sdk/docs/man3/ xhtml/glDepthRange.xml

“裁剪并除以w后,深度坐标范围从-1到1,对应于近和远裁剪平面”,即正z进入屏幕=左手。您还可以使用 DepthRange 更改为右手行为。

编辑:为了回应鲍勃·克罗斯坚持认为我错了,这里有一个源文件程序,表明我是对的。 https://github.com/rswinkle/opengl_reference/blob/master/ src/left_handed.c

可以在README中看到截图
https://github.com/rswinkle/opengl_reference

最终编辑:2020 年 9 月,我发布了 PortableGL。如果有人想了解 OpenGL 管道的内部结构/数学原理,作为一些证据,我知道我在这里所说的是什么:
http://portablegl.com/

The canonical view volume aka normalized device coordinates is/are left-handed. This is easy to test by passing the identity matrix and drawing 2 triangles say

float points[] = { -1,  1,  -0.5,
                   -1, -1,  -0.5,
                    1, -1,  -0.5,

                    1,  1,   0.5,
                   -1, -1,   0.5,
                    1, -1,   0.5 };

and looking at the results (with glEnable(GL_DEPTH_TEST))

So your vertex shader will look like this:

uniform mat4 mvp_mat;

// Incoming per vertex... position (fills in 1 for w if from vec3 buf)
layout (location = 0) in vec4 v_vertex;


void main(void) 
{ 
    // multiplying by identity doesn't transform the geometry
    gl_Position = mvp_mat * v_vertex;
}

or you could even test it more simply like this since the identity matrix does nothing

layout (location = 0) in vec4 v_vertex;

void main(void) 
{
    //no transformation, no confusion, just straight to OpenGL
    gl_Position = v_vertex;
}

Obviously you'll have to make the colors of the triangles different so you can see how they overlap.

Also see this post and my comment/question in it:
plus.google.com/114825651948330685771/posts/AmnfvYssvSe

I don't know where all the incorrect information comes from all over the internet and even in textbooks. OpenGL is only right handed by default if you're talking about triangle winding for determining the front face (CCW by default = right handed). World space, object space and eye space don't exist to OpenGL, only to the graphics programmer. OpenGL just takes points, clips anything outside of the canonical view volume [-1, -1, -1] x [1, 1, 1] and transforms them to screenspace/window coordinates which by default is [0, w) x [0, h) x [0, 1]. If the depth test is enabled the default behavior is left-handed, looking down +z.

There are several ways to account for OpenGL's left-handedness. Most people handle it in their matrices (though they don't realize it). I think you can also change it using glDepthFunc and setting it to GL_GREATER.

http://www.opengl.org/sdk/docs/man3/xhtml/glDepthFunc.xml

Further proof that it is left handed is here
http://www.opengl.org/sdk/docs/man3/xhtml/glDepthRange.xml

"After clipping and division by w, depth coordinates range from -1 to 1, corresponding to the near and far clipping planes" ie positive z goes into the screen = left-handed. You can also use DepthRange to change to right-handed behavior.

EDIT: In Response to Bob Cross's insistence that I'm wrong, here's a single source file program that shows that I'm right. https://github.com/rswinkle/opengl_reference/blob/master/src/left_handed.c

You can see the screenshot in the README
https://github.com/rswinkle/opengl_reference

Final Edit: In September 2020 I released PortableGL. If anyone wants to see the internals/math of the OpenGL pipeline and as some evidence I know what I'm talking about here:
http://portablegl.com/

oО清风挽发oО 2024-10-27 02:20:48

我的问题是,这个坐标是
系统是右手还是左手?

默认情况下,OpenGL 始终是右手的。您可以通过自动法线创建来观察这一点。您可以通过指定每个点来强制进行左手法线创建,但一般来说,右手规则始终适用。请参阅 OpenGL 常见问题解答中的 9.150 了解有关右侧的更多讨论OpenGL 的唯一本质。

...所有数学约定
接下来是 API?

目前尚不清楚你在要求什么。数学是基本的线性代数,重点关注矩阵数学和线性变换。

编辑回答评论问题:

记住,但是,如果您使用统一矩阵调用而不是旧的 glRotates 等,则必须指定是否使用行优先或列优先矩阵。在这种情况下(来自评论中提到的代码):

glUniformMatrix4fv(uniforms[UNIFORM_MVP], 16, GL_FALSE, mvpMatrixZRotation);

在此调用中,GL_FALSE 告诉调用这是一个列主矩阵,因此,结果的旋转将是转置的意图。因此,旋转将被反转,看起来像左手坐标系。

将其更改为GL_TRUE,一切都会好起来的。

这是来自 OpenGL 讨论板的非常简单的示例这与这个特定主题相关。

回应评论请求的另一次编辑这是另一个详细解释OpenGL 中矩阵管道的。请注意具有三个轴的 GL_MODELVIEW 图表:它们说明了右手坐标系。常见问题解答中的上述引文仍然适用。

My question is, is this coordinate
system right-handed or left-handed?

By default, OpenGL is always right-handed. You can observe this by the automatic normal creation. You can force a left-handed normal creation by specifying it per point but, in general, right hand rule applies all the time. See 9.150 in the OpenGL FAQ for more discussion of the right-hand-only nature of OpenGL.

... all the mathematical conventions
followed by the API?

It's not clear what you're asking for. The math is basic linear algebra with a strong focus on matrix math and linear transformations.

EDIT to respond to comment question:

REMEMBER, however, that if you are using the uniform matrix calls rather than the older glRotates, etc, that you must specify whether you are using row-major or column-major matrices. In this case (from the code mentioned in the comment):

glUniformMatrix4fv(uniforms[UNIFORM_MVP], 16, GL_FALSE, mvpMatrixZRotation);

In this call, GL_FALSE is telling the call that this is a column-major matrix and, as such, the rotation that results will be the transpose of what was intended. Therefore, the rotation will be inverted, looking like a left-handed coordinate system.

Change that to GL_TRUE and all will be well.

Here is a very simple example from the OpenGL discussion board that's relevant to this specific topic.

Yet another edit to respond to the request for comment: Here is another detailed explanation of the matrix pipeline in OpenGL. Notice the GL_MODELVIEW diagram with the three axes: they illustrate the right-handed coordinate system. The above citation in the FAQ also still applies.

风筝在阴天搁浅。 2024-10-27 02:20:48

Opengl ES 坐标系确实是右手坐标系,包括 (-1, -1, -1) 到 (1,1,1) 的规范体积。我已经通过代码验证了这一点。

Opengl ES coordinate system is indeed Right Handed System including the Canonical Volume of (-1, -1, -1) to (1,1,1). I have verified this through code.

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