Why would it be beneficial to have a separate projection matrix, yet combine model and view matrix?
当你学习3D编程时,你会学到,用3个转换矩阵最容易思考:
模型矩阵。这个矩阵对每个模型都是独立的,它会根据需要旋转和缩放对象,并最终将其移动到三维世界中的最终位置。"模型矩阵将模型坐标转换为世界坐标。
视图矩阵。对于大量对象(如果不是所有对象),此矩阵通常是相同的,并且它会根据当前"相机位置"旋转和移动所有对象。如果您对由相机拍摄的3D场景进行成像,并且屏幕上呈现的是由该相机拍摄的图像,则相机的位置及其查看方向将定义场景的哪些部分可见,以及对象在拍摄的图像上的显示方式。在渲染单个帧时更改视图矩阵的原因很少,但事实上确实存在这些原因(例如,通过渲染场景两次并在其间更改视图矩阵,可以在场景中创建一个非常简单但令人印象深刻的镜像)。通常,视图矩阵在绘制的两个帧之间只更改一次。"视图矩阵将世界坐标转换为眼睛坐标"。
投影矩阵。投影矩阵决定如何将这些三维坐标映射到二维坐标,例如,如果应用了透视图(对象越远离观察者越小),或不应用透视图(正交投影)。投影矩阵几乎从未改变过。如果渲染到窗口中且窗口大小发生了更改,或者渲染为全屏且分辨率发生了更改,则可能需要更改,但前提是新窗口大小/屏幕分辨率的显示纵横比与以前不同。有一些疯狂的效果,你可能想改变这个矩阵,但在大多数情况下,它在你的程序的整个运行中几乎是恒定的。"投影矩阵将眼睛坐标转换为屏幕坐标。
这对我来说很有意义。当然,一个人可以将所有三个矩阵组合成一个矩阵,因为先将一个向量乘以矩阵
现在,如果你看看经典的OpenGL(OpenGL1.x/2.x),OpenGL知道一个投影矩阵。然而,OpenGL不提供模型或视图矩阵,它只提供组合模型视图矩阵。为什么?此设计强制您永久保存和恢复"视图矩阵",因为它将被应用于它的模型转换"破坏"。为什么没有三个独立的矩阵?
如果您查看新的OpenGL版本(OpenGL3.x/4.x),并且不使用经典的渲染管道,而是使用着色器(glsl)自定义所有内容,那么就根本没有可用的矩阵,您必须定义自己的矩阵。然而,大多数人仍然保留着投影矩阵和模型视图矩阵的旧概念。你为什么要这样做?为什么不使用三个矩阵,这意味着您不必永久地保存和恢复模型视图矩阵,或者使用单个组合模型视图投影(MVP)矩阵,它将矩阵乘法保存在顶点明暗器中,用于渲染任何一个顶点(毕竟这样的乘法也不是免费的)。
所以,总结一下我的问题:与三个单独的矩阵或一个MVP矩阵相比,组合模型视图矩阵和单独的投影矩阵有什么优势?
实际上看看。首先,发送的矩阵越少,与位置/法线/等相乘的矩阵就越少,因此顶点着色速度越快。
所以第1点:矩阵越少越好。
但是,您可能需要做某些事情。除非你是做二维渲染或一些简单的三维演示应用程序,你将需要做照明。这通常意味着您需要将位置和法线转换为世界或相机(视图)空间,然后对它们执行一些照明操作(在顶点明暗器或片段明暗器中)。
如果只从模型空间转到投影空间,就不能这样做。不能在后投影空间中进行照明,因为该空间是非线性的。数学变得复杂得多。
所以,第2点:在模型和投影之间至少需要停一站。
所以我们至少需要2个矩阵。为什么要模型到摄像机而不是模型到世界?因为在世界空间的阴影下工作是个坏主意。您可能会遇到与远离原点的平移相关的数值精度问题。但是,如果您在相机空间工作,则不会遇到这些问题,因为没有任何东西离相机太远(如果是,则可能在远深度平面之外)。
因此:我们使用相机空间作为照明的中间空间。
在大多数情况下,您的明暗器将需要世界中的几何体或眼睛坐标进行明暗处理,因此您必须将投影矩阵与模型和视图矩阵分开。
使您的明暗器将几何体与两个矩阵相乘会损害性能。假设每个模型都有数千个(或更多)顶点,那么在CPU中计算一次模型视图矩阵就更有效了,并且让明暗器做一次更少的mtrix向量乘法。