为什么拥有单独的投影矩阵但结合模型和视图矩阵会有好处?

2024-05-14

当您学习 3D 编程时,您会被告知用 3 个变换矩阵来思考是最简单的:

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

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

  3. 投影矩阵。投影矩阵决定如何将这些 3D 坐标映射到 2D 坐标,例如是否应用了透视(物体距离观察者越远,物体就越小)或不应用透视(正交投影)。投影矩阵几乎不会改变。如果您正在渲染到窗口中并且窗口大小已更改,或者您正在渲染全屏并且分辨率已更改,则它可能必须更改,但前提是新的窗口大小/屏幕分辨率具有与以前不同的显示宽高比。有一些疯狂的效果,您可能想要更改这个矩阵,但在大多数情况下,它在程序的整个运行过程中几乎保持不变。 “投影矩阵将眼睛坐标转换为屏幕坐标”。

这对我来说很有意义。当然,人们总是可以将所有三个矩阵组合成一个矩阵,因为首先将向量乘以矩阵A然后通过矩阵B与向量乘以矩阵相同C, where C = B * A.

现在,如果您查看经典的 OpenGL (OpenGL 1.x/2.x),OpenGL 知道投影矩阵。然而OpenGL不提供模型或视图矩阵,它只提供组合的模型-视图矩阵。Why?这种设计迫使您永久保存和恢复“视图矩阵”,因为它会被应用于它的模型转换“破坏”。为什么不存在三个独立的矩阵?

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

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


实际看看吧。首先,您发送的矩阵越少,您必须与位置/法线等相乘的矩阵就越少。因此,你的顶点着色器速度越快。

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

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

如果您仅从模型空间转到投影空间,则无法做到这一点。您无法在投影后空间中进行照明,因为该空间是非线性的。数学变得更加复杂。

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

所以我们至少需要2个矩阵。为什么是模型到相机而不是模型到世界?因为在着色器的世界空间中工作是一个坏主意。 https://nicolbolas.github.io/oldtut/Positioning/Tut07%20The%20Perils%20of%20World%20Space.html您可能会遇到与远离源的翻译相关的数值精度问题。然而,如果您在相机空间中工作,则不会遇到这些问题,因为没有任何东西距离相机太远(如果是,它可能应该在远深度平面之外)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么拥有单独的投影矩阵但结合模型和视图矩阵会有好处? 的相关文章

  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • QOpenGLFunctions 缺少重要的 OpenGL 函数

    QOpenGLFunctions 似乎缺少重要的函数 例如 glInvalidateFramebuffer 和 glMapBuffer 据我了解 QOpenGLFunctions 加载桌面 OpenGL 函数和 ES 函数的交集 如果是这样
  • openGL转png

    我正在尝试将包含大量纹理 没有移动 的 openGL 编辑 我画的卡片 thx unwind 转换为一个 PNG 文件 我可以在框架的另一部分中使用该文件我正在与 有 C 库可以做到这一点吗 thanks 如果您的意思只是 获取由 Open
  • glEnableVertexAttribArray 中“index”参数的含义以及(可能)OS X OpenGL 实现中的错误

    1 我是否正确理解 要使用顶点数组或VBO进行绘制 我需要所有属性在着色器程序链接之前调用glBindAttribLocation 或者在着色器程序成功链接后调用glGetAttribLocation 然后使用glVertexAttribP
  • WebKit 是否使用 OpenGL 来渲染 CSS 过渡?

    WebKit 是使用 OpenGL 来渲染 CSS 过渡 还是使用软件渲染 WebKit 只是一个前端 这取决于后端和硬件支持 谷歌浏览器使用skia http code google com p skia 作为后端 它可以使用软件或硬件
  • 使用 GLSL 着色器在同一片段着色器中定义的多个子例程类型无法正常工作

    我正在开发一个使用 GLSL 着色器的程序 我编写了 2 种不同的方法来用 2 种不同的方法计算 ADS 环境光 漫反射 镜面反射 着色 为了正确完成这项工作 我使用子例程来使用一种或另一种方法来计算 ADS 着色 这是片段着色器代码的一部
  • 使用draw()而不是eventloop时的pyglet

    我正在尝试用 pyglet 画一个圆 但当我使用 draw 函数而不是 app run 循环时 它是不可见的 有什么建议我可以做什么吗 谢谢 from math import from pyglet gl import window pyg
  • OpenGL 与 Eclipse CDT + MinGW + GLEW + GLFW:未定义的参考

    Edit 与此同时 我已经弄清楚了这一点 并在下面写了详细的答案 我刚刚尝试在 Win7 上从 Express 版本的 MSVC 10 切换到 Eclipse CDT 在配置时遇到了以下简单 OpenGL 代码的问题 在 Visual St
  • NV_path_rendering替代方案[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我刚刚观看了 Siggraph 2012 的一个非常令人印象深刻的演示 http nvidia fullviewmedia com sig
  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还
  • WebGL - 如何传递无符号字节顶点属性颜色值?

    我的顶点由具有以下结构的数组组成 Position colour float float float byte byte byte byte 传递顶点位置没有问题 gl bindBuffer gl ARRAY BUFFER this vbo
  • 无法在 WSL2 上运行 OpenGL

    我尝试在 WSL2 上运行 OpenGL 代码 但在尝试运行可执行文件时出现以下错误 GLFW error 65543 GLX Failed to create context GLXBadFBConfig Unable to create
  • 在 GLUT 中使用鼠标滚轮

    我想在 OpenGL GLUT 程序中使用鼠标滚轮来放大和缩小场景 我怎么做 Freeglut 的 glutMouseWheelFunc 回调与版本相关 并且在 X 中不可靠 使用标准鼠标功能并测试按钮 3 和 4 OpenGlut 对 g
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文
  • 三角形纹理映射OpenGL

    我正在开发一个使用 Marching Cubes 算法并将数据更改为 3D 模型的项目 现在我想在 OpenGL 中为我的 3D 模型使用纹理映射 我首先尝试了一个简单的示例 它将图片映射到三角形上 这是我的代码 int DrawGLSce
  • OpenGL 3.1 中已弃用 glLineStipple

    glLineStipple在最新的 OpenGL API 中已被弃用 它被替换成什么 如果不更换 怎样才能达到类似的效果呢 我当然不想使用兼容性配置文件 抱歉 它还没有被任何东西取代 我想到的第一个模拟它的想法是几何着色器 您向几何着色器提
  • 使用 GLSL 直接在着色器中从位置计算平移矩阵

    我正在开发 C OpengL 程序以及 GLSL 顶点和片段着色器 我正在创建同一对象的多个实例 我只需要改变实例之间的对象位置 这是我所做的 我正在使用一个统一变量 它是一个变换矩阵数组 每个矩阵代表一个对象实例 MVP 也是一个变换矩阵
  • OpenGL:伽玛校正图像看起来不线性

    我使用 OpenGL 进行渲染 当我将线性值写入默认帧缓冲区 没有任何伽玛校正 时 它们在我的显示器上显示为线性 这违背了我认为我所知道的关于伽马校正的一切 如下所述 http gamedevelopment tutsplus com ar
  • 致命错误 gl.h 包含在 glew.h 之前

    include
  • 用于新 Windows 游戏项目的 OpenGL 或 Direct3D?或者是其他东西?

    我正在 Windows 上启动一个爱好游戏项目 该项目将大量使用 3D 图形效果 它很可能是用 C 编写的 我应该使用 OpenGL 还是 Direct3D 作为我的图形后端 为什么 或者我应该使用现成的图形引擎 例如OGRE 3D htt

随机推荐