首页 文章

为什么有一个单独的投影矩阵,但结合模型和视图矩阵是有益的?

提问于
浏览
46

当您学习3D编程时,您会被教导从3个转换矩阵的角度来考虑它是最简单的:

  • 模型矩阵 . 该矩阵对于每个模型都是独立的,它可以根据需要旋转和缩放对象,最后将其移动到3D世界中的最终位置 . "The Model Matrix transforms model coordinates to world coordinates" .

  • 视图矩阵 . 对于大量对象(如果不是对于所有对象),此矩阵通常是相同的,并且它根据当前"camera position"旋转并移动所有对象 . 如果您对相机拍摄3D场景进行成像,并且屏幕上呈现的内容是此相机捕获的图像,则相机的位置及其查看方向定义场景的哪些部分可见以及对象如何出现在捕获的图像上 . 在渲染单个帧时更改视图矩阵几乎没有理由,但实际上存在这些原因(例如,通过渲染场景两次并更改其间的视图矩阵,您可以在场景中创建一个非常简单但令人印象深刻的镜像) . 通常,视图矩阵在绘制的两个帧之间仅改变一次 . "The View Matrix transforms world coordinates to eye coordinates" .

  • 投影矩阵 . 投影矩阵决定这些3D坐标如何映射到2D坐标,例如,如果有一个透视应用于它们(对象变得越小,它们远离观察者)或不(正交投影) . 投影矩阵几乎没有变化 . 如果渲染到窗口并且窗口大小已更改,或者您正在全屏渲染并且分辨率已更改,则可能必须更改,但是仅当新窗口大小/屏幕分辨率具有与以前不同的显示宽高比时 . 有一些疯狂的效果,你可能想要改变这个矩阵,但在大多数情况下,它对你的整个程序来说几乎是不变的 . "The Projection Matrix transforms eye coordinates to screen coordinates" .

这对我来说很有意义 . 当然,总是可以将所有三个矩阵组合成单个矩阵,因为首先将矢量乘以矩阵 A 然后乘以矩阵 B 与将矢量乘以矩阵 C 相同,其中 C = B * A .

现在,如果你看一下经典的OpenGL(OpenGL 1.x / 2.x),OpenGL知道一个投影矩阵 . 然而,OpenGL不提供模型或视图矩阵,它只提供组合的模型视图矩阵 . Why? 此设计强制您永久保存和恢复"view matrix",因为它将通过应用于它的模型转换获得"destroyed" . 为什么没有三个单独的矩阵?

如果你看一下新的OpenGL版本(OpenGL 3.x / 4.x)并且你没有使用经典的渲染管道但是使用着色器(GLSL)自定义所有内容,那么根本就没有可用的矩阵,你必须定义自己的矩阵 . 大多数人仍然保留投影矩阵和模型视图矩阵的旧概念 . Why would you do that? 为什么不使用三个矩阵,这意味着你也不能免费获得 . )

因此,总结一下我的问题:在具有三个单独的矩阵或单个MVP矩阵的情况下,哪个优势具有组合的模型 - 视图矩阵以及单独的投影矩阵?

2 回答

  • 37

    实际上看看它 . 首先,您发送的矩阵越少,您需要与位置/法线/等相乘的矩阵越少 . 因此,顶点着色器越快 .

    所以第1点:更少的矩阵更好 .

    但是,您可能需要做某些事情 . 除非您正在进行2D渲染或一些简单的3D演示应用程序,否则您将需要进行照明 . 这通常意味着您需要将位置和法线转换为世界或相机(视图)空间,然后对它们执行一些照明操作(在顶点着色器或片段着色器中) .

    如果你只是从模型空间到投影空间,你不能这样做 . 您无法在投影后空间中进行照明,因为该空间是非线性的 . 数学变得复杂得多 .

    所以,第2点:你需要在模型和投影之间至少停一次 .

    所以我们需要至少2个矩阵 . 为什么要模型到相机而不是模型到世界?因为working in world space in shaders is a bad idea.您可能会遇到与远离原点的翻译相关的数值精度问题 . 然而,如果你在相机空间工作,你就不会遇到这些问题,因为没有任何东西离相机太远(如果是的话,它可能应该在远深度平面之外) .

    因此:我们使用相机空间作为照明的中间空间 .

  • 2

    在大多数情况下,着色器将需要世界中的几何图形或阴影中的眼睛坐标,因此您必须从模型和视图矩阵中分离投影矩阵 .

    使着色器将几何体与两个矩阵相乘会损害性能 . 假设每个模型都有thousends(或更多)顶点,那么在cpu中计算一次模型视图矩阵就更有效了,让着色器做少一个mtrix-vector multiplication .

相关问题