[英]Opengl - GLM::Ortho + GLM_COORDINATE_SYSTEM = weird?
当我刚接触opengl并很少寻求帮助时,我认为需要对Z轴,深度测试和GLM:ortho进行一些说明。 经过一两个星期的苦苦挣扎,一切从一开始就被“颠倒了”。
所以即时通讯使用:
glDepthFunc(GL_LESS);
glDepthRange(0.0f, 1.0f);
glm::ortho(0.0f, 800, 0.0f, 800), 0.0f, 1.0f);
Okej,所以一切都应该加起来,小Z在前面,大Z在后面,但是没有。 一切都是相反的。
根据该线程和glDepthFunc / glClearDepth的默认值,当将MVP提供给着色器时,所有内容都应在左手坐标中。
因此,当我阅读链接的线程时,我发现glm :: ortho应该将右坐标(因为多数民众赞成在示例中使用的是那)转换为左坐标。 听起来很棒,那为什么不起作用?
当您查看GLM库时,您会发现glm :: ortho,glm :: orthoLH和glm :: orthoRH听起来很有趣。 如果我使用glm :: orthoLH,则所有内容加起来并可以完美地工作,因为它将我所有的坐标转换为左手坐标。 那么,为什么glm :: or不为我这样做呢?
编译GLM库时,显然有一个设置。 GLM_COORDINATE_SYSTEM控制在调用glm :: ortho时系统是否将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是右撇子,是否不需要将正态转换为左撇子?
所以我的问题是
如果这没有任何意义,请纠正我。 我也很困惑:)
我认为您的主要困惑与以下问题有关:
为什么GLM认为OpenGL是右撇子?
OpenGL不是右撇子,也不是左撇子。 OpenGL只是渲染API,而不是坐标系。
在典型的渲染管道中,您确实有很多不同的坐标系,例如:
这些坐标系中的每一个都可以具有自己的约定,包括自己的惯用性。
具有固定功能管线和集成矩阵堆栈的旧版OpenGL考虑了一些坐标约定(但也不能完全强制您使用这些约定)。
因此经典的OpenGL约定是:
规范化的设备空间/窗口空间为左手空间,x指向右侧,y向上,z进入屏幕,右眼空间右手x指向右侧,y向上,摄像机朝-z方向。 对象和世界空间通常也都是惯用右手的(因此视图转换仅是旋转+平移,而没有镜像)。
惯用力的翻转是在投影矩阵中完成的。 传统GL的其他约定没有将近和远的剪辑平面位置始终定义为到查看方向的距离 ,因此glOrtho(..., 2,5)
实际上建立了将z_eye=-2
映射到z_ndc=-1
和z_eye=-5
至z_ndc=1
。
如果您看一下我初次写的映射,它应该解释这个问题:
Okej,所以一切都应该加起来,小Z在前面,大Z在后面,但是没有。 一切都是相反的。
如您所见,“小” z(-5)在后面,而“大” z(-2)在前面,就像它应该在右手坐标系中一样。
当你不设置GLM_FORCE_LEFT_HANDED
,GLM使用遗留GL做了相同的约定。 它将通过在投影矩阵中翻转z来建立右手视图空间(并假定所有后续空间NDC和窗口空间都配置为左手)。
如果您设置了GLM_FORCE_LEFT_HANDED
,它不会引入沿z的一个镜像,但它仍将把near
及far
的距离进入观察方向,这是目前+z
。 这将导致建立左手视图空间(只要NDC和Window空间也被设置为左手视图空间)。
在处理着色器的过程中,OpenGL是否会敏锐地希望MVP是惯用右手的?
这些都是惯例。 您只需要以一种或另一种方式来决定它们,就任何一种说法而言,没有一个比另一个更好。 只有当您使用不同的约定的不同部分或片段时,这些内容才会变得有趣(烦人),您必须非常小心地在正确的位置正确地转换数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.