对 openGL 的相机和相机 space 转换的困惑

confusion on openGL's camera and camera space transformation

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

The author at learnopengl.com mentions本节相机方向单位:

For the view matrix's coordinate system we want its z-axis to be positive and because by default (in OpenGL) the camera points towards the negative z-axis we want to negate the direction vector.

我的问题是:

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

We formulate the view matrix and explicitly apply the transformation in the shader(passing the view matrix or lookAt matrix) as a uniform, so isn't the camera created by us?

是的,没错。甚至在着色器之前也是如此。只有坐标转换,如果我们将其解释为 "camera" 完全取决于我们。

It's not like OpenGL provides us with a default camera object for us to work with, so how does this default camera even come from?

该教程非常不精确here.However,旧版 OpenGL 中有一些默认的约定,但这些只是约定,从未严格要求使用。一些遗留的 OpenGL 功能是用那些设计的 不过,请记住约定。一般的想法是,用户使用右手眼 space,其中 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 为后缀的函数,因此您可以选择你喜欢的约定。

We could assume the axes of our coordinate space pointing any direction right?

是的。但是,剪辑 spacegl_Position 顶点着色器输出在其中)由 GL 定义:光栅化器将始终使用 x 派生的从 x_cip/w_clipy 派生自 y_clip/w_clip ,其中 x 是水平维度, y 是垂直维度。 z 维度仅用于深度测试,如果指向屏幕,我们最终还是选择它(您可以切换深度测试比较方向,或者 glDepthRange,或者两个都)。 GPU 根本不会关心你在中间使用什么,所以对于 object space, world space and _eye_space_,你可以使用任何你喜欢的约定,或者你可以组成完全不同的 spaces 如果它比传统模型更适合你的需要。

最后,3 维归一化设备 space 中的所有内容都会投影到 2 维视口上。归一化设备space是一个立方体,左、下、近为(-1, -1, -1),右、上、远为(1, 1, 1)。
将顶点坐标转换为 homogeneous clipspace coordinates (gl_Position) respectively cartesian 标准化设备 space 坐标的所有转换都由您决定。
(规范化的设备坐标是剪辑 space 坐标除以剪辑坐标的 w 分量。这称为 Perspective divide

标准化设备 space 是左手系统(参见 Left- vs. Right-handed coordinate systems respectively Right-hand rule)。通常我们想使用右手系统。所以在某些时候,坐标必须从右手系统转换为左手系统。通常,这是由投影矩阵完成的,它反转(镜像)Z 轴。

反正没必要"by default (in OpenGL) the camera points towards the negative z-axis"。这是一个规范问题,但通常使用这样的视图坐标系。


进一步了解 Why is the z coordinate flipped after multiplying with a matrix in GLSL - OpenGL