对 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.
我的问题是:
- 我们制定视图矩阵并明确应用变换
在着色器中(传递视图矩阵或 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()
都将 near
和 far
视为正数到观察方向的距离,但分别对近平面使用 z_eye = -near
,对远平面使用 z_eye = -far
。他们还将下行设置为 0,0,-1,0
,因此我们最终将透视除以 -z_eye
并得到左手 NDC 坐标系(其中 z_ndc
指向现在屏幕)。
请注意,glm
中的矩阵函数也遵循这些约定,但您还会发现以名称 LH
和 RH
为后缀的函数,因此您可以选择你喜欢的约定。
We could assume the axes of our coordinate space pointing any direction right?
是的。但是,剪辑 space(gl_Position
顶点着色器输出在其中)由 GL 定义:光栅化器将始终使用 x
派生的从 x_cip/w_clip
和 y
派生自 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
在指定 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.
我的问题是:
- 我们制定视图矩阵并明确应用变换 在着色器中(传递视图矩阵或 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()
都将 near
和 far
视为正数到观察方向的距离,但分别对近平面使用 z_eye = -near
,对远平面使用 z_eye = -far
。他们还将下行设置为 0,0,-1,0
,因此我们最终将透视除以 -z_eye
并得到左手 NDC 坐标系(其中 z_ndc
指向现在屏幕)。
请注意,glm
中的矩阵函数也遵循这些约定,但您还会发现以名称 LH
和 RH
为后缀的函数,因此您可以选择你喜欢的约定。
We could assume the axes of our coordinate space pointing any direction right?
是的。但是,剪辑 space(gl_Position
顶点着色器输出在其中)由 GL 定义:光栅化器将始终使用 x
派生的从 x_cip/w_clip
和 y
派生自 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