Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >我对GLM lookAt函数理解中的一个矛盾

我对GLM lookAt函数理解中的一个矛盾
EN

Stack Overflow用户
提问于 2014-01-15 18:57:10
回答 2查看 3.9K关注 0票数 4

首先,如果您想要解释GLM lookAt算法,请看这个问题的答案:https://stackoverflow.com/a/19740748/1525061

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mat4x4 lookAt(vec3  const & eye, vec3  const & center, vec3  const & up)
{
vec3  f = normalize(center - eye);
vec3  u = normalize(up);
vec3  s = normalize(cross(f, u));
u = cross(s, f);

mat4x4 Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] =-f.x;
Result[1][2] =-f.y;
Result[2][2] =-f.z;
Result[3][0] =-dot(s, eye);
Result[3][1] =-dot(u, eye);
Result[3][2] = dot(f, eye);
return Result;
}

现在我要告诉你们为什么我似乎对这个算法有一个概念上的问题。该视图矩阵分为平移和旋转两部分。翻译进行正确的逆变换,将相机位置转换为原点,而不是原点位置到摄像机。类似地,您也期望相机定义的旋转在放入此视图矩阵之前被反转。我看不出这里发生了什么,这是我的问题。

考虑前向矢量,这是你的相机看的地方。因此,这个正向向量需要映射到-Z轴,这是openGL使用的正向方向。这个视图矩阵的工作方式是在视图矩阵的列中创建一个正交基,所以当你在这个矩阵的右边乘一个顶点时,你实际上只是把它的坐标转换成不同的轴。

当我在脑海中进行旋转时,我看到的不是相机的反向旋转,而是应该发生的旋转,而是非逆的旋转。也就是说,我发现-Z轴不是前向映射到-Z轴,而是向前映射到摄像机轴。

如果你不明白我的意思,请考虑一个2D例子,这个例子就是发生在这里的同一类型的事情。假设前向矢量是(sqr(2)/2,sqr(2)/2),或者sin/cos是45度,我们也可以说,这个2D相机的侧矢量是sin/cos = -45度。我们要把这个正向量映射到(0,1),正Y轴。正Y轴可以看作是与-Z轴在openGL空间中的类比。让我们考虑一个与前向向量相同方向的顶点,即(1,1)。通过使用GLM.lookAt的逻辑,我们应该能够使用一个2x2矩阵将(1,1)映射到Y轴,该矩阵由第一列中的前向向量和第二列中的侧向量组成。这是计算+1的等效计算。

注意,你没有得到你的(1,1)顶点映射成你想要的正Y轴,而是把它映射到正X轴。如果应用此转换,还可以考虑位于正Y轴上的顶点发生了什么。果然,它被转换成正向向量。

因此,GLM算法似乎有些可疑之处。然而,我怀疑这个算法是不正确的,因为它是如此流行。我遗漏了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-17 14:20:35

查看Mesa:http://cgit.freedesktop.org/mesa/glu/tree/src/libutil/project.c中的GLU源代码

首先,在gluPerspective的实现中,注意-1使用的是索引[2][3]-2 * zNear * zFar / (zFar - zNear)使用的是[3][2]。这意味着索引是[column][row]

现在,在gluLookAt的实现中,第一行设置为side,下一行设置为up,最后一行设置为-forward。这给了你旋转矩阵,它是后乘的平移,把眼睛带到原点。

GLM似乎使用相同的[column][row]索引(从代码)。您刚刚为lookAt发布的文章与更标准的gluLookAt (包括平移部分)是一致的。所以至少GLM和GLU都同意。

然后,我们逐步推导出完整的构造。注意C的中心位置和E的眼睛位置。

  1. 移动整个场景,将眼睛的位置放在原点,即应用-E的翻译。
  2. 旋转场景,使相机的轴线与标准的(x, y, z)轴对齐。 2.1计算相机的正正交基础: F=正规化(C- E) (指向中心)s=正规化(F X u) (指向右眼)u=s x f(指向上方) 有了这一点,(s, u, -f)是相机的正正交基础。 2.2找到旋转矩阵R,它将(s, u, -f)轴映射到标准轴(x, y, z)。逆旋转矩阵R^-1做相反的工作,并将标准轴对齐到摄像机轴,根据定义这意味着: (sx ux -fx) R^-1 = (sy uy -fy) (sz uz -fz) 自R^-1 = R^T以来,我们有: ( sx sy )R=( ux uy uz) (-fx -fy -fz)
  3. 把平移和旋转结合起来。一个点M被“查看”转换到R (M - E) = R M - R E = R M + t映射。因此,用于“查看”的最后4x4转换矩阵确实是: ( sx sz tx )( sy sz -s.E )L=( ux uy uz ty )=( ux uz -u.E ) (-fx -fy -fz tz ) (-fx -fy -fz f.E )(0 0 0 1)(0 0 0 1)

所以当你写:

也就是说,我发现-Z轴不是前向映射到-Z轴,而是向前映射到摄像机轴。

这是非常令人惊讶的,因为通过构造,“查看”转换将相机的前向轴映射到-z轴。这种“看”转换应该被认为是移动整个场景,使相机与标准的原点/轴对齐,这才是它真正要做的。

使用您的2D示例:

通过使用GLM.lookAt的逻辑,我们应该能够使用一个2x2矩阵将(1,1)映射到Y轴,该矩阵由第一列中的前向向量和第二列中的侧向量组成。

相反,按照我描述的构造,您需要一个2x2矩阵,将前向和行向量映射为行,而不是列来映射(1,1),并将另一个向量映射到y和x轴。要使用矩阵系数的定义,需要通过变换得到标准基向量的图像。这直接给出矩阵的列。但是因为你要寻找的是相反的(将你的向量映射到标准的基向量),你必须将转换(转置,因为它是一个旋转)。然后你的参考向量变成行而不是列。

票数 5
EN

Stack Overflow用户

发布于 2014-01-16 00:26:48

这些人可能会对你的可疑问题有更深入的了解:glm::lookAt vertical camera flips when z <= 0

你可能对答案感兴趣吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21152556

复制
相关文章
xp默认管理员账户隐藏问题
很多用户在新装winxp之后没有去创建系统账户,而是使用最高权限的默认管理员账户。
horsley
2022/08/16
6720
gitlab修改管理员用户邮箱
背景: 参照https://www.yuque.com/duiniwukenaihe/znm95g/fmpmzk内网搭建了一台gitlab服务器。嗯 然后我要测试webhook触发jenkins流水线
对你无可奈何
2021/04/30
2.7K0
非 Kubernetes 管理员,清库跑路手册
但是也有可能没那么大权限,那么就试试下面的方法吧。下面的方法依赖于 Docker 的特权模式。
陈少文
2021/01/24
4430
非 Kubernetes 管理员,清库跑路手册
管理员组的非Administrator用户有时候改不了hosts
有时候系统有特殊配置,可能Administrators组的非Administrator用户打开的cmd不对(不是以管理员身份打开的),通过命令行改或直接去改C:\Windows\System32\drivers\etc\hosts,都改不了
Windows技术交流
2022/09/20
7290
给当前用户添加管理员权限
在打开的对话框中输入管理员组“administrators”,并单击“检查名称”按钮,如下图:
wsuo
2020/07/31
3.3K0
给当前用户添加管理员权限
Discourse 如何指派用户管理员权限
但是 Discourse 的管理员用户组是没有办法从用户组上添加用户的,你需要登录 Discourse 的后台后,找到你希望指派的用户,然后将这个用户指定为管理员。
HoneyMoose
2020/10/21
1.9K0
Discourse 如何指派用户管理员权限
mac用户丢失管理员身份急救
用了这么久mac,发现居然还存在这么大一个bug。就是如果你曾经编辑mac电脑默认用户资料,比如试图改用户名、试图改HOME路径之类的,有很高比率可能导致该用户丧失管理员权限。 随后悲剧就开始了,所有需要管理员权限认证的地方,比如安装了一个新软件,在弹出的认证窗口中,无论如何输入用户名和密码,都无法授权通过。此时在系统设置->用户及用户组中,会发现该用户选项卡中“允许用户管理这台电脑”前面的勾选已经不见了。当然这时候因为无法授权修改用户权限,因此也无法重新勾选上这个选项。 解决方法一: 这个是通常的
俺踏月色而来
2018/06/15
3.4K0
Oracle 数据库管理员及管理员的作用
以下测试实例均在Oracle11gr2下测试!!! 一、简介:每个Oracle数据库应该至少有一名数据库管理员(dba),对于一个小的数据库,一个dba就够了,但是对于一个大的数据库,可能需要多个dba分担不同的管理职责,以下是一个数据库管理员的工作职责: 1、安装和升级Oracle数据库 2、建库、表空间、表、视图、索引等常用的数据对象 3、制定并实施备份与恢复计划 4、数据库权限管理,调优,故障排除 5、对于高级dba,要求能参与项目开发,会编写sql语句、存储过程、触发器、规则、约束、包等 二、Ora
郑小超.
2018/01/26
1.8K0
Windows 下使用 runas 命令以指定的权限启动一个进程(非管理员、管理员)
在默认情况下,Windows 系统中启动一个进程会继承父进程的令牌。如果父进程是管理员权限,那么子进程就是管理员权限;如果父进程是标准用户权限,那么子进程也是标准用户权限。
walterlv
2023/10/22
7.2K0
Windows 下使用 runas 命令以指定的权限启动一个进程(非管理员、管理员)
绕过反病毒添加管理员用户小结
我们在后渗透中时常会遇到这样的环境,即使成功拿到了目标机器的Admin/System权限后也不能添加用户和管理员组,出现这种情况的原因有很多,如:UAC、WAF、反病毒软件或者是net.exe降权和安全组策略中的软件限制、应用程序控制策略等。
潇湘信安
2021/01/22
3.3K0
绕过反病毒添加管理员用户小结
WordPress中判断用户是不是管理员
今天在写个小程序,需要判断指定用户的角色是不是网站管理员,如知道用户的id是123,想要知道他是不是管理员。
主机优惠教程
2022/04/09
8750
获取域内管理员和用户信息
如果我们拿到了一台普通用户权限的windows计算机,想要在内网中横向移动,需要知道域内用户登录的位置,是否是本地管理员,他的组,是否有权访问文件共亨等等。
黑白天安全
2020/07/30
8.1K0
获取域内管理员和用户信息
红队战术-从域管理员到企业管理员
一个企业的整个网络划分是非常巨大了,甚至有多个林,而这个域森林权力最大还属企业管理员了,当我们拿到一个域的dc的时候,当然不是红队的终点,我们的最终的目标是企业管理员,只要我们拿下了企业管理员,整个企业内网才算真正拿下。
Gamma实验室
2021/07/01
1.1K0
启动管理员进程
当我们运行一个程序的时候有时需要提升到管理员权限,但是默认的C#程序的运行权限是当前用户的权限,那么怎么提升这个启动权限呢?
用户1175783
2019/09/18
7880
动物管理员 --- zookeeper
简单地说就是管理员。有什么事它就会通知到所有被它管理的人。就比如宿舍管理员,宿舍要停电他就会发通知,然后所有住这栋楼的都会知道。说专业一点,它是由文件系统和通知机制组成的。
贪挽懒月
2020/01/15
7480
动物管理员 --- zookeeper
功能亮点:CPU管理员
作者:Balaji Subramaniam(英特尔),Connor Doyle(英特尔)
CNCF
2019/12/05
6080
Jenkins修改管理员密码.
前言:Jenkins修改管理员密码,我看了网上所有的教程,竟然全都是拿着一串已经加密好的111111的密文去替代config.xml文件里面的密码,然后大家的密码都是111111!我觉得这种做法实在太敷衍了!于是我就研究了下,包括Jenkins密码的加密方式,以及如何修改管理员的密码,当然,通过配置Jenkins允许注册用户,去注册一个用户,也不失为一个好选择。 1、Jenkies的加密方式 Jenkins的密码采用的是Java加解密工具 jBCrypt,我也是第一次接触到这种加密方式,实在被他惊叹到
JMCui
2018/03/15
2K0
Jenkins修改管理员密码.
gitlab重置管理员密码
在公司内,所有的代码业务都是部署在gitlab搭建的内网仓库中的,但是一次断电后,我忘记了管理密码,其余人的密码也忘记了想要重置,但是邮件都是默认的,没有设置自己的邮件,所以只能我在后台操作 忘记gitlab管理账号密码时候的解决方案: > 在服务器终端输入 gitlab-rails console production > 进入到git shell中输入 user = User.where(id:1).first user.password = 'Your password' user.save
简单、
2018/06/21
1.8K0
网站管理员工具简介
在众多谷歌网站管理员工具指南资料中,能够视频和文字结合实操的为数不多。本博主在咨询培训过程中经常碰到不会使用谷歌网站管理员工具的,为了谷歌SEO用户提供最好地使用网站管理员工具专门推出此系列指南。
林雍岷
2019/07/03
9980
MySQL管理员密码重设
输入:mysqld --defaults-file="MySQL地址加\my.ini" --init-file="文件地址" --console
Breeze.
2022/05/01
1.4K0
MySQL管理员密码重设

相似问题

sharepoint隐藏非管理员的管理员标题

20

非管理员用户显示隐藏项

23

SQL条件,管理员用户与非管理员用户

221

通过管理员或非管理员

11

向非管理员的用户隐藏的新闻源

22
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文