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

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(使用前将#替换为@)

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

  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还
  • PyQt5 的 OpenGL 模块和版本控制问题(调用不正确的 _QOpenGLFunctions_(ver))

    我一直在努力得到PyQt5 helloGL 示例代码 https github com baoboa pyqt5 blob master examples opengl hellogl py编译 当我尝试构建解决方案时 我得到 Traceb
  • 在 GLUT 中使用鼠标滚轮

    我想在 OpenGL GLUT 程序中使用鼠标滚轮来放大和缩小场景 我怎么做 Freeglut 的 glutMouseWheelFunc 回调与版本相关 并且在 X 中不可靠 使用标准鼠标功能并测试按钮 3 和 4 OpenGlut 对 g
  • 将带有 glut 的点击坐标添加到向量链接列表中

    我想创建一个向量链接列表 并在 GLUT 库的帮助下获取点击的位置并将它们附加到链接列表中 这些是我写的结构 typedef struct vector int x int y Vector typedef struct VectorLis
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 根据 GLSL 中向量的特定分量执行最小-最大的最快方法?

    我需要在我的 GLSL 代码中多次调用这种函数 vec2 minx vec2 a vec2 b if a x lt b x return a else return b 我担心过度分支 有没有办法避免 if else 结构 我建议使用 GL
  • gldrawarrays 不绘制任何东西

    我正在尝试用 VBO 绘制一个三角形 我在窗口上没有看到任何像素 我也没有看到任何 GL ERROR 这是我尝试运行的代码 include
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • GLSL - 测试片段值

    假设你有一个vec3 colourIn从一个vertex shader to a frag shader 有没有办法测试一个值并根据需要覆盖它 例如 将任何蓝色值大于0 5的片段设置为白色 In my Shader frag我实施了这个测试
  • 简单的openGL程序无法在ubuntu中链接

    我正在尝试进入 opengl 编程 但无法编译我的第一个非常非常简单的程序 链接过程每次都会失败 我发现这个答案 https stackoverflow com questions 859501 learning opengl in ubu
  • 如何在 Visual Studio 2012 中安装 GLUT 和 OpenGL?

    我今天刚安装了Visual Studio 2012 我想知道如何在该平台上安装GLUT和OpenGL OpenGL 应该已经存在 可能会缺少 Freeglut GLUT GLUT 现在已经非常过时并且没有得到积极的支持 所以你当然应该使用
  • 在windows + opengl中选择图形设备

    我知道如何使用 openGL 打开窗口 使用 Win32 或其他工具包 但是当系统有2块显卡时 如何选择要渲染的图形设备 我的编程语言是 C 我专注于 Windows 但任何示例都将受到欢迎 编辑 也许更好地解释我的问题是个好主意 以便添加
  • 纹理的内部格式

    看下面的OpenGL函数 void glTexImage2D GLenum target GLint level GLint internalFormat GLsizei width GLsizei height GLint border
  • glVertexAttribDivisor 和 glVertexBindingDivisor 有什么区别?

    我一直在寻找将属性与任意顶点分组关联起来的方法 起初似乎是我实现这一目标的唯一方法 但后来我偶然发现了这个问题 https stackoverflow com questions 14169228 opengl single vertex
  • 云或烟雾的粒子系统

    我正在尝试使用 OpenGL 和 CUDA 制作一个简单的用于云和烟雾模拟的粒子系统 如何使粒子系统中的粒子表现得像真正的云或烟雾在低湍流风中的表现 我现在遇到的一些问题是 颗粒聚集成一个大球 粒子扩散到无限远 粒子突然弹射离开 我已经完成
  • glColor4f() - alpha 值的效果

    我正在使用 glColor4f 令人惊讶的是 更改 alpha 即第四个参数 不会导致透明度发生任何变化 代码段是 const GLfloat squareVertices 0 5 0 5 0 0 0 5 0 5 0 0 0 5 0 5 0
  • GLSL 中统一浮点行为和常量浮点行为的不同

    我正在尝试在 GLSL 中实现模拟双精度 并且观察到一种奇怪的行为差异 导致 GLSL 中出现细微的浮点错误 考虑以下片段着色器 写入 4 浮点纹理以打印输出 layout location 0 out vec4 Output unifor
  • 使用 glGetFloatv 检索 pyglet 中的模型视图矩阵

    我正在使用 pyglet 在 python 中进行 3D 可视化 并且需要检索模型视图和投影矩阵来进行一些选择 我使用以下方式定义我的窗口 from pyglet gl import from pyglet window import wi
  • 移动/调整大小期间 opengl 窗口冻结

    我正在使用 LWJGL 开发游戏 移动窗口时 计划将来添加调整大小代码 渲染循环冻结 我希望它在移动时继续以某种方式运行 LWJGL 不包括 glutMainLoop Display属于OpenGL 而不是Java 相关代码 regular
  • 渲染具有透明度的纹理时,OpenGL 不需要的像素

    我已经为这个问题苦苦挣扎了一段时间了 当我使用 OpenGL 渲染 2D 纹理 在无透明度和部分透明度之间的过渡上具有透明度值 时 我得到了一些烦人的灰色像素 我认为这是像素值插值的产物 关于如何改进这一点有什么想法吗 I m attach

随机推荐