矩阵/向量乘法顺序

2024-03-29

我在网上阅读了十几篇关于 OpenGL 中旋转、平移和缩放矩阵乘法的正确顺序的文章。然而,现在我开始自己实现它,我真的很困惑。

假设在我的代码中我正在计算变换矩阵,并将其作为一个结果矩阵传递给着色器:

shader.SetUniform("u_Matrix", scale * rotation * translation);

在顶点着色器中,我将顶点乘以这个矩阵:

gl_Position = u_Matrix * vec4(a_Position, 0.0, 1.0);

现在,按照这个顺序(缩放*旋转*平移)我得到了我想要的: 我旋转对象,然后将其移动到特定点,然后缩放它。 有人能解释一下为什么这是正确的顺序吗?

我一直认为所有的变换都是“从矢量端”应用的。

例如,如果我们“展开”乘法:

gl_Position = scale * rotation * translation * vec4(a_Position, 0.0, 1.0);

那么首先应该应用平移,然后应用旋转和缩放。如果不是平移和旋转的顺序,一切对我来说似乎都很好。如果我们不想绕某个点旋转,我们应该先旋转,然后平移,但这里不是这种情况。

为什么这种转变能够按预期进行?


您的 C++ 矩阵可能在幕后存储为行主。这意味着从左到右将它们相乘是“原点”变换,而从右到左则是“局部”增量变换。

然而,OpenGL 使用列主排序内存布局(16 元素数组中的第 13、14 和 15 个元素被视为转换组件)。

要在 OpenGL 中使用行主矩阵,您可以执行以下两件事:

  1. glUniformMatrix*()函数,有一个参数将 GL_TRUE 传递给transpose争论:

    void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    

    这会将它们重新安排为专栏专业。

  2. 另一种是恢复着色器中操作的顺序:

    gl_Position = vec4(a_Position, 0.0, 1.0) * u_Matrix;
    

    但您会发现的大多数 GLSL 文献都会使用本地从左到右的列主要排序,因此最好坚持使用。

另一种选择是更改 C++ 端的布局,使它们成为列主(但我个人认为行主更容易处理)。

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

矩阵/向量乘法顺序 的相关文章

  • 为什么在 Javascript 中添加两位小数会产生错误的结果? [复制]

    这个问题在这里已经有答案了 可能的重复 JavaScript 的数学有问题吗 https stackoverflow com questions 588004 is javascripts math broken 为什么 JS 搞砸了这个简
  • 优雅的折线“左移”测试

    Given X Y 坐标 即车辆的位置 X Y 数组 它们是折线中的顶点 请注意 折线仅由直线段组成 没有圆弧 我想要的是 计算车辆是在折线的左侧还是右侧 当然还是在顶部 我的做法 迭代所有线段 并计算到每个线段的距离 然后 对于最近的段
  • WebKit 是否使用 OpenGL 来渲染 CSS 过渡?

    WebKit 是使用 OpenGL 来渲染 CSS 过渡 还是使用软件渲染 WebKit 只是一个前端 这取决于后端和硬件支持 谷歌浏览器使用skia http code google com p skia 作为后端 它可以使用软件或硬件
  • CPU是如何做减法的?

    我有一些基本的疑问 但每次我坐下来尝试面试问题时 这些问题和我的疑问就会出现 假设 A 5 B 2 假设A和B都是4字节 那么CPU是怎么做的呢 A B添加 我知道 A 的符号位 MSB 为 0 表示正值 B 的符号位为 1 表示负整数 现
  • C++ 求矩阵最小和最大元素之间的元素和

    因此 我的程序按其应有的方式工作 但前提是最小和最大元素位于对角 所以我的问题是如何将二维数组从一个特定元素迭代到另一个元素 也许摆脱一些嵌套循环 我应该将这个数组转换为一维吗 这是代码的正确工作方式 就在这时 出现了问题 元素 0 1 和
  • Eclipse 标记 OpenGL 函数无法解析

    我尝试在 Eclipse C C 中使用一些 OpenGL 函数 一些 标准 函数如 GlClear 可以被 eclipse 识别 而其他函数如 glBindBuffer 和 glEnableVertexAttribArray 则不能 它们
  • 确定范围是否重叠

    给定两个具有整数开始时间和结束时间的事件 E1 s1 e1 E2 s2 e2 实现快速布尔检查以查看事件是否重叠 我有解决方案 但我很想看看其他人想出了什么 编辑 好的 这是我的解决方案 e1 gt s2 s1 gt s2 e2 lt s1
  • 使用draw()而不是eventloop时的pyglet

    我正在尝试用 pyglet 画一个圆 但当我使用 draw 函数而不是 app run 循环时 它是不可见的 有什么建议我可以做什么吗 谢谢 from math import from pyglet gl import window pyg
  • CSS3 矩阵 3d 矩形到梯形的转换

    我正在尝试使用 webkit 对 CSS3 的支持transform matrix3d
  • 以一定角度遍历二维数组

    通常我们按行或列遍历数组 但这里我想以角度遍历它 我会尝试解释我的意思 因此 假设角度是 45 度 那么它会搜索为 0 0 then 0 1 1 0 then 0 2 1 1 2 0 等等 抱歉 无法上传图像 因为我是新用户 不允许这样做
  • 方案中的多维向量?

    我之前问过一个关于方案中数组的问题 结果它们被称为向量 但在其他方面基本上与您期望的相同 有没有一种简单的方法可以在 PLT 方案中处理多维 arrays 向量 出于我的目的 我想要一个名为make multid vector或者其他的东西
  • Python 小数.InvalidOperation 错误

    当我运行这样的东西时 我总是收到此错误 from decimal import getcontext prec 30 b 2 3 Decimal b Error Traceback most recent call last File Te
  • 错误 C2039:“find”:不是“std”的成员

    我刚刚遇到一个奇怪的错误 它说 find 不是 std 的成员 错误 C2039 find 不是 std 的成员 错误 C3861 查找 未找到标识符 基本上 我想查找是否可以在向量中找到字符串 知道为什么会发生这种情况吗 代码帮助告诉我
  • 按度数在圆上找到一个点?

    假设我们有一个 100x100 坐标系 如下所示 0 0 是它的左上角 50 50 是它的中心点 100 100 是它的右下角 等等 现在我们需要从中心向外画一条线 我们知道线的角度 但需要计算其终点的坐标 您认为最好的方法是什么 例如 如
  • 小数除以小数并得到零

    为什么当我这样做时 select CAST 1 AS DECIMAL 38 28 CAST 1625625 AS DECIMAL 38 28 我得到 0 吗 但是当我得到 0 时 select CAST 1 AS DECIMAL 20 10
  • 如何通用地减少子集平均值的计算?

    Edit 由于似乎没有人阅读此链接的原始问题 因此让我在这里介绍一下它的概要 正如其他人所问的 最初的问题是 给定大量值 总和将超过数据类型的值Double那么如何计算这些值的平均值呢 有几个答案说要按集合计算 比如取50个和50个数字 计
  • SDL 鼠标位置调整大小后裁剪

    我在 SDL 中的鼠标位置上遇到了一些奇怪的行为 如果我将窗口大小调整得更大 则任一鼠标事件的 x y 位置似乎都限制为原始窗口的宽度和高度 如果我缺少一些函数调用来告诉 SDL 鼠标区域的大小已增加 应用程序的相关部分 void Resi
  • 从 1D 列表创建 2D 列表

    我对 Python 有点陌生 我想将一维列表转换为二维列表 给定width and length这个的matrix 说我有一个list 0 1 2 3 我想做一个2 by 2该列表的矩阵 我怎样才能得到matrix 0 1 2 3 widt
  • 使用 sapply 的列表和矩阵

    我有一个也许是基本的问题 我在网上搜索过 我在读取文件时遇到问题 尽管如此 我还是按照 Konrad的建议设法读取了我的文件 我很欣赏这一点 How to get R to read in files from multiple subdi
  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还

随机推荐

  • TensorFlow 对象检测 API - 内存不足

    我正在使用 Tensorflow 对象检测 API 来训练我自己的对象检测器 我下载了faster rcnn inception v2 coco 2018 01 28来自模型动物园 here https github com tensorf
  • isalpha() 给出一个断言

    我有一个 C 代码 其中在 ctype h 中使用标准库函数 isalpha 这是在 Visual Studio 2010 Windows 上 在下面的代码中 如果 char c 是 则 isalpha 调用将返回一个断言 如下面的快照所示
  • 模式切换是否发生从用户线程切换到内核线程?

    我对用户 内核线程和模式 上下文切换感到困惑 平台 Linux 我有两个相关的问题 1 下列句子正确的是 如果我进行系统调用 则会发生模式切换 用户模式到内核模式 并最终从用户线程切换到内核线程 由于系统调用只能在内核线程中执行 因此我认为
  • Define True,如果不定义,会导致语法错误

    我今天在别人的代码中发现了以下构造 try True False except NameError True 1 1 False 1 0 据我了解 它定义了True and False如果它们尚未定义 因此 如果定义了它们 则不应抛出Nam
  • 在 Rails 中制作用户年龄的饼图

    我的用户模型中有这个函数可以计算用户年龄 def get age now Time now utc to date now year dob year now month gt dob month now month dob month n
  • Ionic:Android 模拟器错误

    我正在尝试使用 Android Studio v3 0 附带的 Android 模拟器来测试我的 Ionic 3 16 0 混合应用程序 myapp gt ionic cordova build android成功创建构建 但当我跑步时 m
  • 画布在鼠标事件上获取点

    我有以下函数来获取鼠标单击位置 坐标 myCanvas on click function e event e event event window event var canvas document getElementById myCa
  • 适用于 Windows 的 Docker 桌面

    我正在尝试在我的 Windows 10 Pro 64 位计算机上运行 Docker 桌面 其构建规范和设置详细信息如下 版本 Windows 10 专业版 64 位 版本 1903 操作系统版本 18362 657 CPU 英特尔 i7 H
  • MySql触发器更新选择插入后的总和

    我有三张桌子 Members Accounts 交易 在将新事务插入事务表后 我想用所有 Transactions TransactionAmount 的总和更新 Accounts AccountBalance 以下代码似乎对我不起作用 有
  • 不幸的是 已停止

    所以我不知道关于双重帖子的规则是什么 任何我在其他问题上没有得到后续支持的人 任何我的问题被陈述的人 这是我的 logcat 05 28 19 45 03 464 I ActivityManager 274 Start proc xela
  • UnicodeEncodeError:“ascii”编解码器无法对位置 47 中的字符 u'\u2019' 进行编码:序数不在范围内(128)

    我正在使用 Python 2 7 和 MySQLdb 1 2 3 我尝试了在 stackoverflow 和其他论坛上找到的所有内容来处理我的脚本抛出的编码错误 我的脚本从源 MySQL 数据库中的所有表中读取数据 并将它们写入 pytho
  • django modelformset_factory 中的 MultiValueDictKeyError

    我正在尝试实现一个编辑表单集 然后 我使用 modelformset factory 实例化表单集中的对象 当请求不是 POST 时 表单集会完美加载 但是 如果请求是 POST 则表单集构造函数会引发 MultiValueDictKeyE
  • 出口交易需要客户名称和地址 - Stripe 错误

    我正在使用 stripe SDK 创建客户并使用 API 向客户收费 但出现错误 致命错误 未捕获 状态 400 请求 req ZyqUtykjUcOqrU 根据印度法规 出口交易需要客户名称和地址 更多信息请参见 https stripe
  • SQL Server 逆透视两列

    我正在尝试旋转表格以获得 3 列 我的示例表如下 CREATE TABLE tbl1 A1 int cA1 int A2 int cA2 int A3 int cA3 int GO INSERT INTO tbl1 VALUES 60 2
  • Wt C++ Web 框架的主机,部署问题

    我想知道 justhost com 是否足以托管 Wt C 网站 应用程序 它确实允许 FTP 和 SSH 访问http richelbilderbeek nl CppWtDeployGlobalHosted htm http richel
  • pyinstaller 是否有像 gcc -static 这样的参数?

    我有一个类似的问题 有没有办法将 Python 程序编译为二进制并将其与 Scratch Dockerfile 一起使用 https stackoverflow com questions 62581924 is there a way t
  • 在给定图上绘制水平线

    如何向现有绘图添加水平线 Use axhline https matplotlib org stable api as gen matplotlib pyplot axhline html 水平轴线 例如 这会在以下位置绘制一条水平线y 0
  • GUI 中的 __init__ 与 tkinter

    我正在学习使用 Tkinter 使用 python 创建简单的 GUI 我目前正在使用 python 文档作为参考 link http docs python org 2 library tkinter html 我想做的第一件事是理解那里
  • Spark:从 RDD[X] 生成所有可能组合的 RDD[(X, X)]

    Spark 中是否可以从 scala 集合中实现 combinations 函数 Iterates over combinations return An Iterator which traverses the possible n el
  • 矩阵/向量乘法顺序

    我在网上阅读了十几篇关于 OpenGL 中旋转 平移和缩放矩阵乘法的正确顺序的文章 然而 现在我开始自己实现它 我真的很困惑 假设在我的代码中我正在计算变换矩阵 并将其作为一个结果矩阵传递给着色器 shader SetUniform u M