何时使用四元数表示缩放和旋转是合适的并且是优选的(由于速度,稳定性等)在三个维度上,而不是相应的变换矩阵上?
#1 楼
我想从一个误解入手:现代GPU(相当一段时间以来,NVIDIA以及从Southern Islands开始的AMD)并没有真正地支持硬件中的矢量/矩阵运算。它们是沿不同方向的向量体系结构:向量的每个分量(x,y,z)通常具有32或64值,其中包含泳道中每个元素的值。因此3D点乘积通常不是指令,它是一个乘法和两个乘法加法。
另外,对诸如乘法加法之类的原始运算进行计数,通过四元数转换向量比转换更昂贵一个矩阵向量用3x3矩阵变换向量是3个乘法和6个乘法加法,用四元数变换向量是两个四元数乘法,每个四元数乘法包括4个乘法和12个乘法加法。 (您可能会比这更幼稚-这是一种更快的方法-但它仍然不如将向量乘以矩阵便宜。)
但是,性能并非总是通过计数来确定它执行的ALU操作数。四元数比等效矩阵需要更少的空间(假设您仅在进行纯旋转/缩放),这意味着更少的存储空间和更少的内存流量。这在动画中通常很重要(四元数的漂亮插值属性通常也很方便出现)。
除此之外:
矩阵使用更多空间,因为它们支持更多操作。 3x3矩阵可以包含不均匀的比例尺,偏斜,反射和正交投影。
自然可以将矩阵视为基本矢量,并可以轻松地从这些矢量中构建。
一个四元数与另一个四元数相乘(组成两个旋转)。 )比将一个矩阵乘以另一个要少。
评论
$ \ begingroup $
有趣的是,在Intel Haswell GPU上,ARBfp的DP3指令实现为3乘2加,请参阅Intel Linux驱动程序的INTEL_DEBUG = fs输出:paste.ubuntu.com/23150494。不确定是驱动不良还是硬件确实没有特殊的矢量mul指令。
$ \ endgroup $
–俄罗斯
16 Sep 8'在15:14
$ \ begingroup $
@Ruslan很可能该硬件没有特殊的矢量mul指令。尽管它们确实更准确,但它们是在体系结构的SIMD宽度(通道)上向量化的,而不是在vec3 / vec4维度上向量化的。
$ \ endgroup $
– John Calsbeek
16年8月8日在18:17
#2 楼
(在这里,我无情地从joojaa和棘轮怪胎的答案中借来了很多信息,并附带了一些自己的注释。)矩阵优势
非均匀缩放和旋转,偏斜,投影
平移(除非使用双四元数)
本机硬件支持
四元数通常需要先验函数来构造
更容易理解
四元数优点
变换向量需要较少的操作(或者不是-参见John的答案)
用另一个quat进行变换所需的操作更少
四元数占据4个浮点,(8 (如果是对偶),但矩阵占据9-16个浮点数
如果您只打算进行统一的刚体变换,则矢量/四对通常在3x4矩阵上是一个坚实的胜利在存储空间(向量/ quat:7或8个浮点数与mat3x4:12个浮点数)和处理速度方面。如果四元数仍然对您来说是神秘的伏都教,请尝试在其上使用此网络系列。
#3 楼
与四元数相比,矩阵提供了更多可能的变换,它可以倾斜,镜像和非均匀缩放矩阵。没有任何内容表明,如果不需要其他转换功能,就无法使引擎仅执行基于四元数的转换。当您需要在需要知道的位置构建空间时,矩阵非常方便基本向量。例如在对正交进行投影时。在矩阵空间中进行透视变换也很容易。
以某种方式通常使用矩阵,因为它们代表最常见的面额,并且不太容易掌握和理解。标准化的好处远远超过了从自定义工作流程中获得的好处。它众所周知的如何做矩阵运算。 qua并不是uni中最容易立即介绍的东西。只是问周围有多少人知道如何反转四元数,而没有找到很多不知道如何反转矩阵的学生。
请注意,图形卡还具有用于矩阵操作的专用管道。
评论
$ \ begingroup $
我实际上一直在考虑这个。 Ive还开玩笑地问,除了可以使用矩阵和quat层次结构之外,还可以使用什么其他方法对管道进行建模。
$ \ endgroup $
– joojaa
2015年8月9日下午13:17
#4 楼
四元数只能表示均匀的缩放和旋转,因此如果需要其他任何内容,则需要添加一些内容来表示。可以使用单个附加vec3(或使用双四元数)进行翻译。但是,用mat4可以更好地表示不均匀的缩放和收缩。投影变换(本质上是不均匀的缩放以及交换z和w)不能用四元数表示。
四元数在插值时具有很大的优势。使用四元数最容易计算出slerp。
GPU中未内置应用四元数(或双四元数)的功能,因此您需要使用矢量运算来实现。大多数四元数库都假定您不会使用四元数来表示比例,因此需要注意。
评论
另请参阅GameDev SE上的相关问题。