为什么有一个单独的投影matrix,然而结合模型和视图matrix是有好处的?

当你在学习3D编程时,你会被教导最简单的3个变换matrix:

  1. 模型matrix 。 这个matrix是每个单独的模型的个体,它旋转和按比例缩放对象,最终将其移动到3D世界中的最终位置。 “模型matrix将模型坐标转换为世界坐标”。

  2. 查看matrix 。 这个matrix对于大量的对象通常是相同的(如果不是全部),它将根据当前的“摄像头位置”旋转和移动所有的对象。 如果您想要使用相机拍摄3D场景,并且屏幕上显示的是由本相机拍摄的图像,则相机的位置及其观看方向将定义场景的哪些部分是可见的以及对象出现在捕获的图像上。 在渲染一个单独的帧的时候改变视图matrix的理由很less,但实际上存在(例如,通过渲染场景两次,改变视图matrix,你可以在场景中创build一个非常简单但令人印象深刻的镜像) 。 通常情况下,视图matrix在绘制的两个帧之间只改变一次。 “查看matrix将世界坐标转换为眼坐标”。

  3. 投影matrix 。 投影matrix决定如何将这些3D坐标映射到2D坐标,例如,如果有一个应用于它们的视angular(物体越远离观察者越小)或不正确(正交投影)。 投影matrix几乎不会改变。 但是,只有当新的窗口大小/屏幕分辨率具有与以前不同的显示宽高比时,如果要渲染到窗口中并且窗口大小已更改,或者如果您正在渲染全屏并且分辨率已更改,则可能必须更改。 有一些疯狂的效果,你可能想要改变这个matrix,但在大多数情况下,它对你的程序的整个生活非常稳定。 “投影matrix将眼坐标转换为屏幕坐标”。

这对我来说很有意义。 当然,总是可以将所有三个matrix合并成一个matrix,因为先乘以matrixA然后乘以matrixB与将matrixC乘以向量相同,其中C = B * A

现在,如果你看看经典的OpenGL(OpenGL 1.x / 2.x),OpenGL知道投影matrix。 然而,OpenGL不提供模型或视图matrix,它只提供了一个组合的模型视图matrix。 为什么? 这种devise迫使你永久地保存和恢复“视图matrix”,因为它将被应用于它的模型转换“消灭”。 为什么没有三个单独的matrix?

如果您查看新的OpenGL版本(OpenGL 3.x / 4.x),并且不使用经典的渲染pipe线,而是使用着色器(GLSL)自定义所有内容,则不再需要matrix,您必须定义你自己的matrix。 大多数人仍然保留投影matrix和模型视图matrix的旧概念。 为什么要这么做? 为什么不使用三个matrix,这意味着您不必永久保存和恢复模型视图matrix,或者使用单个组合的模型 – 视图 – 投影(MVP)matrix,这可以节省您在顶点着色器中的matrix乘法为所有渲染的单个顶点(毕竟这样的乘法不是免费的)。

所以总结一下我的问题:哪一个优点有一个组合的模型 – 视图matrix和一个单独的投影matrix,而不是有三个独立的matrix或单个MVPmatrix?

实际上看它。 首先,你发送的matrix越less,你必须乘以位置/法线等的matrix越less。 因此,顶点着色器速度越快。

所以点1:matrix越less越好。

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

如果你只从模型空间到投影空间,你不能这样做。 你不能在后投影空间做照明,因为这个空间是非线性的。 math变得更加复杂。

所以,第2点:你需要在模型和投影之间至less有站。

所以我们至less需要2个matrix。 为什么模型到相机而不是模型到世界? 因为在着色器的世界空间工作是一个坏主意。 您可能会遇到与距离原点较远的翻译相关的数值精度问题。 而如果你在相机空间工作,你不会遇到这些问题,因为没有太多的距离相机(如果是的话,它应该可能在远距离的平面之外)。

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

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

使你的着色器乘以两个matrix的几何会伤害性能。 假设每个模型都有多个(或多个)顶点,则在CPU中计算模型视图matrix一次会更高效,并让着色器执行less一个matrix向量乘法。