为什么投影矩阵可以正确调整坐标?
Why the projection matrix can adjust the coordinates correctly?
我从 OpenGL ES Android development guide 看到说“...投影矩阵重新计算图形的坐标,以便它们正确映射到 Android 设备屏幕。”
的确,在我乘以项目矩阵后,一个简单的正方形在我的 phone 上正确呈现,但我很好奇魔法是如何工作的。 (我的直觉是模型矩阵应该做比例工作)
谁能在不涉及太多计算机图形背景的情况下用简单的语言解释一下?
如果您的目标是 OpenGL ES 1.0,则有 OpenGL 固定功能管道。这里我们有 GL_PROJECTION
和 GL_MODELVIEW
矩阵堆栈(实际上还有另一个用于纹理操作,但这与这里无关)。
发生的事情是固定功能管道只是 concatenates/multiplies 这两个矩阵堆栈的顶部矩阵(对于投影矩阵和模型视图,我们将它们称为 P
和 MV
矩阵,分别)作为 P * MV
在每个绘制调用期间并通过 P * MV * v
.
转换任何绘制的顶点 v
当您以 OpenGL ES 2.0 或更高版本为目标时,不再有此类固定功能矩阵堆栈,但您将使用着色器并上传您自己的矩阵(例如作为制服或通过其他方式)。在那里,您完全可以自由决定如何分解最终转换(以前在固定功能管道中 P * MV
)。最后,您要做的就是将顶点从它们的 space(通常称为“模型 space”)转换为“剪辑 space”坐标。 Clip space 是 OpenGL ES 2.0(或更高版本)真正关心的唯一东西。
只是将最终矩阵(模型 -> 剪辑 space)分解为投影、视图和模型矩阵很方便,因为它们在整个场景渲染过程中会发生变化。投影矩阵通常只包含那些保持不变的变换,并且只需要在调整 window 大小时(或重新配置垂直视野)时刷新。也就是说,这个矩阵从“view space”转换为“clip space”,代表了相机的内在属性。
现在,在大多数情况下,还有一个专用的“视图”矩阵,它表示相机的外部属性,通常是相机的位置和方向世界。因此,当您 rotate/move 虚拟相机时,此矩阵会发生变化。这个矩阵从“模型”转换为“视图”space.
接下来是模型矩阵,它代表了世界上每个模型的转换。
最后,当你想渲染任何东西时,你会使用分解 P * V * M
(投影矩阵乘以视图矩阵乘以模型矩阵)通过整个模型链变换一个顶点 ->剪辑 space.
现在回答为什么我们在投影矩阵中进行缩放的问题:
原因是一旦你进入视图 space(在 GL_MODELVIEW 转换或你的自定义 V * M
转换之后),你有一个 space 的轴是与屏幕对齐。因此,您知道要缩放什么(X 或 Y 轴)以及缩放多少。您不能简单地缩放模型,因为它也可能被任意旋转和平移。
我从 OpenGL ES Android development guide 看到说“...投影矩阵重新计算图形的坐标,以便它们正确映射到 Android 设备屏幕。”
的确,在我乘以项目矩阵后,一个简单的正方形在我的 phone 上正确呈现,但我很好奇魔法是如何工作的。 (我的直觉是模型矩阵应该做比例工作)
谁能在不涉及太多计算机图形背景的情况下用简单的语言解释一下?
如果您的目标是 OpenGL ES 1.0,则有 OpenGL 固定功能管道。这里我们有 GL_PROJECTION
和 GL_MODELVIEW
矩阵堆栈(实际上还有另一个用于纹理操作,但这与这里无关)。
发生的事情是固定功能管道只是 concatenates/multiplies 这两个矩阵堆栈的顶部矩阵(对于投影矩阵和模型视图,我们将它们称为 P
和 MV
矩阵,分别)作为 P * MV
在每个绘制调用期间并通过 P * MV * v
.
v
当您以 OpenGL ES 2.0 或更高版本为目标时,不再有此类固定功能矩阵堆栈,但您将使用着色器并上传您自己的矩阵(例如作为制服或通过其他方式)。在那里,您完全可以自由决定如何分解最终转换(以前在固定功能管道中 P * MV
)。最后,您要做的就是将顶点从它们的 space(通常称为“模型 space”)转换为“剪辑 space”坐标。 Clip space 是 OpenGL ES 2.0(或更高版本)真正关心的唯一东西。
只是将最终矩阵(模型 -> 剪辑 space)分解为投影、视图和模型矩阵很方便,因为它们在整个场景渲染过程中会发生变化。投影矩阵通常只包含那些保持不变的变换,并且只需要在调整 window 大小时(或重新配置垂直视野)时刷新。也就是说,这个矩阵从“view space”转换为“clip space”,代表了相机的内在属性。
现在,在大多数情况下,还有一个专用的“视图”矩阵,它表示相机的外部属性,通常是相机的位置和方向世界。因此,当您 rotate/move 虚拟相机时,此矩阵会发生变化。这个矩阵从“模型”转换为“视图”space.
接下来是模型矩阵,它代表了世界上每个模型的转换。
最后,当你想渲染任何东西时,你会使用分解 P * V * M
(投影矩阵乘以视图矩阵乘以模型矩阵)通过整个模型链变换一个顶点 ->剪辑 space.
现在回答为什么我们在投影矩阵中进行缩放的问题:
原因是一旦你进入视图 space(在 GL_MODELVIEW 转换或你的自定义 V * M
转换之后),你有一个 space 的轴是与屏幕对齐。因此,您知道要缩放什么(X 或 Y 轴)以及缩放多少。您不能简单地缩放模型,因为它也可能被任意旋转和平移。