-2

我得到了一个围绕 y 轴旋转的 3 个顶点三角形。我发现“奇怪”的一件事是 GL 默认正交投影中的归一化坐标。我使用过像 SDL 和 SFML 这样的二维库,它们几乎总是处理像素。你说你想要一个 50x50 像素的图像表面,这就是你得到的。所以最初我说将我的顶点位置选择限制在 [-1,1] 是很奇怪的。

为什么必须对正交坐标进行归一化?透视投影是一样的吗?如果是这样,您如何说您希望对象的原点位于 z=-10?(我对矩阵 m 的快速浏览说视角是不同的。关于除以 'w' 创建同质(与归一化相同?)坐标的东西,但我不确定)。

gl_Position = 视图 * 模型 * 项目 * 顶点;

我已经看到了上面的等式,我对着色器中使用的变量 gl_Position 如何表示模型/对象的当前顶点的位置以及同时表示视图/投影的位置或相机。这是如何运作的?我通过乘法了解所有信息都存储在一个矩阵中,但是OpenGL如何使用这个矩阵,其信息现在组合起来说:“好的,gl_Position的这部分/部分是用于相机的,而另一部分是用于模型要去哪里。”?(顺便说一句,我不太确定 Vertex vec4 代表什么。我认为模型的所有顶点都在模型内部。有什么想法吗?

还有一个问题,如果您只是想移动相机,例如在 FPS 游戏中,您将鼠标向上移动以查看,但除了相机之外没有任何物体被旋转或平移(我认为),上面的等式会看起来像吗像这样?

gl_Position = 查看 * 项目;

4

2 回答 2

5

为什么必须对正交坐标进行归一化?

他们没有。您可以根据需要设置正交投影体积的限制。glOrtho 调用的 left、right、bottom、top、near 和 far 参数定义了视口体积的限制。如果您选择它们​​ left=0, right=win_pixel_width, bottom=0, top=win_pixel_height 您最终会得到一个您习惯的像素单位投影体积。但是,为什么要打扰像素呢?您只需要稍后补偿实际的窗口大小。只需选择正射投影体积范围以匹配您要绘制的场景。

也许您将其与标准化设备坐标混淆了。对于那些它只是被定义为映射到视口范围的值范围 [-1, 1]。

更新

顺便说一句,我不太确定 Vertex vec4 代表什么。我认为模型的所有顶点都在模型内部。有任何想法吗?

我现在很累,因为在过去的几天里,我已经多次回答过这样的几个问题。所以,又来了:

在 OpenGL 中没有相机。

在 OpenGL 中没有场景。

在 OpenGL 中没有模型。

“等等,什么?!” 你现在可能想知道。但这是真的。

OpenGL 所关心的是,有一些目标帧缓冲区,即它可以绘制到的画布,以及构成几何图元的顶点属性流。基元是点、线和三角形。不知何故,必须将三角形的顶点属性映射到帧缓冲区画布上的某个位置。为此,我们称为位置的顶点属性会经历许多仿射变换。

首先是从局部模型空间到世界空间的模型变换。

从世界空间到眼睛空间,视图变换。正是这种视图变换,其作用就像将相机放置在场景中一样。

之后,它通过了相当于相机镜头的投影变换。

在 Projection 变换之后,位置在剪辑空间中,在那里它经历了一些操作,这些操作暂时不需要理解。在裁剪之后,通过将裁剪空间位置向量除以其自身的 w 分量,应用所谓的同质除法以达到归一化的设备坐标空间。

v_position_ndc = v_position_clip / v_position_clip.w

这一步是使透视投影真正起作用的原因。顶点位置的 z 距离被处理到剪辑空间 w 分量中。并且通过具有较大位置 w 的同质分割顶点在 XY 平面中按比例缩放为 1/w,从而产生透视效果。

您将此操作误认为是标准化,但事实并非如此!

在同质划分顶点位置从剪辑映射到 NDC 空间之后。而OpenGL定义,NDC空间的可见体积是框 [-1, 1]^3 ;此框外的顶点被剪裁。

了解视图变换和投影是不同的至关重要。对于一个位置,它不是那么明显,但是另一个称为法线的顶点属性,它是照明计算的重要组成部分,必须以稍微不同的方式进行转换(而不是Projection · View · Model必须转换为inverse(transpose(View · Model)),即投影不参与其中但观点确实如此)。

矩阵本身是 4×4 实数值标量网格(暂时忽略计算机中的数字始终是有理数)。所以矩阵的秩是 4,因此它必须乘以维度 4 的向量(因此类型vec4

OpenGL 将顶点属性视为列向量,因此矩阵乘法是左关联的,即向量在右侧输入表达式并从左侧输出。矩阵乘法的顺序很重要。你不能自由地重新排序东西!

该声明

gl_Position = Projection * View * Model * vertex_position; // note the order

使顶点着色器执行我刚刚描述的这个转换过程。

于 2012-12-28T12:09:49.063 回答
0

“请注意,OpenGL中没有单独的相机(视图)矩阵。因此,为了模拟变换相机或视图,必须使用视图变换的逆来变换场景(3D对象和灯光)。换句话说, OpenGL 定义相机始终位于 (0, 0, 0) 并面向眼睛空间坐标中的 -Z 轴,并且不能进行变换。有关 GL_MODELVIEW 矩阵的更多详细信息,请参见 ModelView Matrix。

来源: http: //www.songho.ca/opengl/gl_transform.html

这就是我要挂断的。我认为在 OpenGL 中会有一个单独的相机视图矩阵。

于 2012-12-28T18:36:39.320 回答