Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 为什么有一个单独的投影矩阵,但将模型和视图矩阵结合起来是有益的?_Opengl_Glsl - Fatal编程技术网

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

Opengl 为什么有一个单独的投影矩阵,但将模型和视图矩阵结合起来是有益的?,opengl,glsl,Opengl,Glsl,当您学习3D编程时,您会被告知,根据3个变换矩阵最容易思考: 模型矩阵。该矩阵对每个模型都是独立的,它会根据需要旋转和缩放对象,并最终将其移动到三维世界中的最终位置。“模型矩阵将模型坐标转换为世界坐标” 视图矩阵。对于大量对象(如果不是所有对象),此矩阵通常是相同的,并且它根据当前“摄影机位置”旋转和移动所有对象。如果使用相机拍摄3D场景,并且屏幕上渲染的是该相机捕获的图像,则相机的位置及其查看方向将定义场景的哪些部分是可见的,以及对象在捕获图像上的显示方式。渲染单个帧时更改视图矩阵的原因很少,

当您学习3D编程时,您会被告知,根据3个变换矩阵最容易思考:

  • 模型矩阵。该矩阵对每个模型都是独立的,它会根据需要旋转和缩放对象,并最终将其移动到三维世界中的最终位置。“模型矩阵将模型坐标转换为世界坐标”

  • 视图矩阵。对于大量对象(如果不是所有对象),此矩阵通常是相同的,并且它根据当前“摄影机位置”旋转和移动所有对象。如果使用相机拍摄3D场景,并且屏幕上渲染的是该相机捕获的图像,则相机的位置及其查看方向将定义场景的哪些部分是可见的,以及对象在捕获图像上的显示方式。渲染单个帧时更改视图矩阵的原因很少,但事实上确实存在(例如,通过渲染两次场景并在其间更改视图矩阵,可以在场景中创建一个非常简单但令人印象深刻的镜像)。通常,视图矩阵在绘制的两个帧之间仅更改一次。“视图矩阵将世界坐标转换为眼睛坐标”

  • 投影矩阵。投影矩阵决定如何将这些三维坐标映射到二维坐标,例如,是否对其应用了透视(对象离观察者越远越小)或不应用透视(正交投影)。投影矩阵几乎从不改变。如果渲染到窗口且窗口大小已更改,或者渲染全屏且分辨率已更改,则可能必须更改,但是,仅当新窗口大小/屏幕分辨率的显示宽高比与以前不同时,才需要更改。有一些疯狂的效果,你可能想改变这个矩阵,但在大多数情况下,它几乎在你的整个节目现场保持不变。“投影矩阵将眼睛坐标转换为屏幕坐标”

  • 这对我来说很有意义。当然,人们总是可以将所有三个矩阵组合成一个矩阵,因为向量首先乘以矩阵
    a
    ,然后再乘以矩阵
    B
    ,这与向量乘以矩阵
    C
    是一样的,其中
    C=B*a

    现在如果你看看经典的OpenGL(OpenGL 1.x/2.x),OpenGL知道一个投影矩阵。然而OpenGL并没有提供模型或视图矩阵,它只提供了一个组合模型视图矩阵为什么?此设计强制您永久保存和恢复“视图矩阵”,因为它将被应用于它的模型转换“破坏”。为什么没有三个独立的矩阵

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


    因此,总结一下我的问题:与三个单独的矩阵或单个MVP矩阵相比,组合模型视图矩阵和单独的投影矩阵有哪些优势?

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


    使着色器将几何体与两个矩阵相乘会影响性能。假设每个模型有一千个端点(或更多个端点)顶点一次在cpu中计算一个模型视图矩阵会更有效,并让着色器少做一次mtrix向量乘法。

    实际观察一下。首先,发送的矩阵越少,与位置/法线等相乘的矩阵就越少。因此,顶点着色器的速度就越快

    所以第1点:矩阵越少越好

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

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

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

    所以我们至少需要2个矩阵。为什么模型到摄影机而不是模型到世界?因为你可能会遇到与远离原点的平移相关的数值精度问题。然而,如果你在摄影机空间工作,你不会遇到这些问题,因为没有什么东西离摄影机太远(如果是,则可能位于远深度平面之外)


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

    照明,当然!我根本没有考虑照明。这可能是因为我迄今为止从未编写过自己的着色器来执行任何照明。在投影空间中无法再进行照明似乎是相当合乎逻辑的。此外,在GPU运算速度非常快——iirc,他们有专用硬件并行实现,所以一个完整的4x4乘4x4矩阵乘法大约是