OpenGL相机和相机空间转型的困惑

confusion on openGL's camera and camera space transformation

本文关键字:相机 空间 OpenGL 转型      更新时间:2023-10-16

在指定model-view变换时,我们需要三个向量来定义相机的局部轴,即direction vector(相机指向的位置)、up vector和相机的right vector,在这三个轴中,direction vector是相机的局部Z轴。

learnopengl.com的作者在本节的相机方向单元中提到:

对于视图矩阵的坐标系,我们希望其z轴为正,并且由于默认情况下(在OpenGL中)相机指向负z轴,我们希望否定方向向量。

我的问题是:

  1. 我们制定视图矩阵并显式应用变换在着色器中(传递视图矩阵或lookAt矩阵)作为制服,所以相机不是我们创造的吗它不像OpenGL为我们提供了一个默认的相机对象供我们使用,那么如何这个默认相机是从哪里来的?我们可以假设轴我们的坐标空间指向任何方向,对吗

我们制定视图矩阵并显式应用转换在着色器(通过视图矩阵或lookAt矩阵)中,那么相机不是我们创造的吗?

没错。甚至在着色器出现之前也是如此。只有坐标变换,如果我们把它解释为"相机",那完全取决于我们

OpenGL并没有为我们提供默认的相机对象要使用,那么这个默认相机是怎么来的呢?

这里的教程非常不精确。然而,在传统OpenGL中有一些默认的约定,但这些只是约定,从未严格要求使用。一些遗留的OpenGL函数是用不过,要记住惯例。一般的想法是,用户使用右手眼睛空间,其中x指向右侧,y向上,z在屏幕外指向观看者,因此-z是观看方向。旧的gluLookat()函数遵循这些约定。

同样,创建投影矩阵的旧函数也遵循这一点:glFrustum()glOrtho()gluPerspecitve()都将nearfar作为观看方向的正距离,但分别将z_eye = -near用于近平面,将z_eye = -far用于远平面。他们还将下一行设置为0,0,-1,0,因此我们最终用-z_eye进行持久除法,并由此得到左手NDC坐标系(z_ndc现在指向屏幕)。

请注意,glm中的矩阵函数也是按照这些约定建模的,但您也会发现函数后缀为LHRH,因此您可以选择自己喜欢的约定。

我们可以假设坐标空间的轴指向任何方向,对吗?

是。但是,剪辑空间(gl_Position顶点着色器输出所在)由GL定义:光栅化器将始终使用源自x_cip/w_clipx和源自y_clip/w_clipy,其中x为水平维度,y为垂直维度。z维度仅用于深度测试,如果它指向屏幕,我们最终将再次选择(您可以切换深度测试比较方向,或glDepthRange,或两者都切换)。GPU根本不在乎你在这两者之间使用什么,所以对于对象空间世界空间

最后,三维标准化设备空间中的所有内容都投影在二维视口上。标准化的设备空间是一个左、下、近为(-1,-1,-1),右、上、远为(1,1,1)的立方体
所有将顶点坐标转换为齐次裁剪空间坐标(gl_Position)和笛卡尔归一化设备空间坐标的转换都由您决定
(标准化的设备坐标是剪辑空间坐标除以剪辑坐标的w分量。这称为透视分割)

标准化的设备空间是一个左手坐标系(分别参见左手坐标系和右手坐标系右手规则)。通常我们想要使用右手系统。因此,在某个时刻,cooridantes必须从右手系统转变为左手系统。通常,这是由投影矩阵完成的,它反转(镜像)Z轴。

无论如何,绝对没有必要"默认情况下(在OpenGL中)相机指向负z轴">。这是一个规范问题,但通常使用这样的视图坐标系。


请进一步了解为什么z坐标与GLSL-OpenGL中的矩阵相乘后会翻转