【发布时间】:2011-03-02 13:33:59
【问题描述】:
假设我在 OpenGL ES 2.0 程序上为我的 modelViewTransformation 矩阵使用了一个身份矩阵。本例中的坐标系是规范的 OpenGL 坐标系,从 (-1,-1,-1) 延伸到 (1,1,1)。
这个坐标系是右手还是左手?
一个更广泛的问题:是否有包含 OpenGL 的文档可以列出 API 遵循的所有数学约定?
【问题讨论】:
标签: opengl-es coordinate-systems
假设我在 OpenGL ES 2.0 程序上为我的 modelViewTransformation 矩阵使用了一个身份矩阵。本例中的坐标系是规范的 OpenGL 坐标系,从 (-1,-1,-1) 延伸到 (1,1,1)。
这个坐标系是右手还是左手?
一个更广泛的问题:是否有包含 OpenGL 的文档可以列出 API 遵循的所有数学约定?
【问题讨论】:
标签: opengl-es coordinate-systems
ALWAYS REMEMBER!! OPENGL ONLY KNOWS NDC ,AND IT IS LEFT_HANDED!
openGL 是右手的错觉,因为在固定管道中,固定函数是右手的,如 glOrtho(...)、glFrustrum(..),所有这些函数在可编程管道时代已被弃用。
OpenGL 并不关心您在中间矩阵过程中使用的手坐标系。如果需要,您可以使用轴坐标系,只要将其镜像到 NDC 即可。
忘记相机!
因为我们的屏幕是一个 2D 平面。想象一下,您的视口是一个黄色的橡胶平面。将这四个角松到 NDC。像这样的东西:
NDC 中的所有顶点沿 -z 轴命中黄色橡胶平面。这就是您在真实屏幕上看到的。
【讨论】:
我的问题是,这个坐标是 系统是右手还是左手?
默认情况下,OpenGL 总是用右手的。您可以通过自动正常创建来观察这一点。您可以通过指定每个点来强制创建左手法线,但通常右手规则始终适用。请参阅9.150 in the OpenGL FAQ,了解更多关于 OpenGL 仅右手性质的讨论。
...所有的数学约定 然后是 API?
不清楚您要的是什么。数学是基本的线性代数,重点关注matrix math and linear transformations。
编辑回复评论问题:
记住,但是,如果您使用的是统一矩阵调用而不是旧的 glRotates 等,则必须指定您使用的是行优先还是列优先矩阵。在这种情况下(来自评论中提到的代码):
glUniformMatrix4fv(uniforms[UNIFORM_MVP], 16, GL_FALSE, mvpMatrixZRotation);
在此调用中,GL_FALSE 告诉调用这是一个以列为主的矩阵,因此,产生的旋转将是预期的转置。因此,旋转将被反转,看起来像一个左手坐标系。
将其更改为GL_TRUE,一切都会好起来的。
这是来自 OpenGL 讨论板的与此特定主题相关的 very simple example。
响应评论请求的另一个编辑:OpenGL 中矩阵管道的Here is another detailed explanation。注意带有三个轴的GL_MODELVIEW 图:它们说明了右手坐标系。常见问题解答中的上述引用仍然适用。
【讨论】:
规范化的视图体积也就是标准化的设备坐标是/是左手的。这很容易通过传递单位矩阵并绘制 2 个三角形来测试
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 };
并查看结果(使用 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 更改为右手行为。
编辑:作为对 Bob Cross 坚持认为我错了的回应,这里有一个单一的源文件程序表明我是对的。 https://github.com/rswinkle/opengl_reference/blob/master/src/left_handed.c
您可以在 README 中查看屏幕截图 https://github.com/rswinkle/opengl_reference
【讨论】:
Opengl ES 坐标系确实是右手系统,包括 (-1, -1, -1) 到 (1,1,1) 的规范体积。我已经通过代码验证了这一点。
【讨论】: