Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?相关的知识,希望对你有一定的参考价值。

虽然我是opengl的新手并且很少寻求帮助,但我认为需要对Z轴,深度测试和GLM:ortho进行一些澄清。与此争吵了一两个星期,一切都从一开始就“逆转”了。

所以即时使用:

  • glDepthFunc(GL_LESS);
  • glDepthRange(0.0f, 1.0f);
  • glm::ortho(0.0f, 800, 0.0f, 800), 0.0f, 1.0f);
  • Z轴为Y / 800(高度),Y = 20的物体落后于Y = 10。

Okej,所以一切都应该加起来,小Z在前面,后面大,但没有。一切都是相反的。

根据这个thread和glDepthFunc / glClearDepth的默认值,当MVP被提供给着色器时,一切都应该在左手坐标中。

因此,当我读到链接的线程时,我发现glm :: ortho应该将右手坐标(因为这显然是每个人在示例中使用的东西)转换为左手坐标。听起来不错,为什么它不起作用?

当你查看GLM库时,你会发现glm :: ortho,glm :: orthoLH和glm :: orthoRH听起来非常苛刻。如果我使用glm :: orthoLH,一切都会加起来并且完美无缺,因为它将我的所有坐标转换为左手坐标。那么为什么glm :: ortho不适合我呢?

在编译GLM库时,显然有一个设置。当调用glm :: ortho时,GLM_COORDINATE_SYSTEM控制系统是否将默认使用glm :: orthoLH或glm :: orthoRH。令我惊讶的是,glm :: orthoLH不是默认值。

如果你查看GLM的源代码,你会发现这些行,

#define GLM_LEFT_HANDED                         0x00000001      // For DirectX, Metal, Vulkan
#define GLM_RIGHT_HANDED                        0x00000002      // For OpenGL, default in GLM

#ifdef GLM_FORCE_LEFT_HANDED
#       define GLM_COORDINATE_SYSTEM GLM_LEFT_HANDED
#else
#       define GLM_COORDINATE_SYSTEM GLM_RIGHT_HANDED
#endif

OpenGL是右撇子,不需要将ortho转换为左手?

所以我的问题是,

  • 为什么GLM认为OpenGL是右撇子?
  • 在处理着色器时,OpenGL是否真的想要MVP作为右手?

如果这没有任何意义,请纠正我。我很困惑:)

答案

我认为你的主要困惑与这个问题有关:

为什么GLM认为OpenGL是右撇子?

OpenGL不是右撇子,也不是左撇子。 OpenGL只是一个渲染API,而不是一个坐标系。

在典型的渲染管道中,您确实有许多不同的坐标系,例如:

  • 对象空间/模型空间
  • 世界空间
  • 眼睛空间/相机空间/视图空间
  • 剪辑空间
  • 标准化设备坐标
  • 窗口空间

这些坐标系中的每一个都可以拥有自己的约定,包括它自己的惯用手法。

具有固定功能管道和集成矩阵堆栈的传统OpenGL考虑了一些坐标约定(但它并未完全强制您使用这些约定)。

所以经典的OpenGL约定是:

标准化的设备空间/窗口空间左手,x指向右,y向上,z指向屏幕,眼睛空间右手x向右,y向上,相机向-z方向看。对象和世界空间通常也只是右手(因此视图转换只是旋转+平移,没有镜像)。

在投影矩阵中完成手性的翻转。传统GL的其他惯例是近距离和远距离剪裁平面位置总是被定义为观察方向的距离,所以glOrtho(..., 2,5)确实建立了一个转换,将z_eye=-2映射到z_ndc=-1z_eye=-5z_ndc=1

如果你看一下我刚写的映射,它应该解释这个问题:

Okej,所以一切都应该加起来,小Z在前面,后面大,但没有。一切都是相反的。

如你所见,“小”z(-5)在后面,“大”z(-2)在前面,就像它应该在右手坐标系中。

当你没有设置GLM_FORCE_LEFT_HANDED时,glm使用与传统GL相同的约定。它将通过在proejction矩阵中翻转z来建立右手视图空间(并假设所有后面的空间NDC和窗口空间都配置为左手)。

如果你设置GLM_FORCE_LEFT_HANDED,它将不会引入沿z的镜像,但它仍然会将nearfar视为距观察方向的距离,现在是+z。这将产生建立左手视图空间的结果(只要NDC和Window空间也设置为左手)。

在处理着色器时,OpenGL是否真的想要MVP作为右手?

这些都只是惯例。你必须以某种方式决定它们,没有人比其他人更好。如果你有不同的部分或部分使用不同的约定,这些东西只会变得有趣(而且很烦人),你必须非常小心地在正确的地方正确地转换数据。

以上是关于Opengl - GLM :: Ortho + GLM_COORDINATE_SYSTEM =很奇怪?的主要内容,如果未能解决你的问题,请参考以下文章

初识OpenGL (-)坐标空间

OpenGL中的正交投影问题

为啥 z 坐标没有被 glm::ortho() 投影归一化?

Ortho 和 Persp 正在反转 Z 深度符号?

了解 glm::ortho() 的参数如何影响投影后的顶点位置

orthoProject freetype opengl