GLSL:用旋转矢量旋转?

Jon*_*han 2 c opengl glsl

我正在尝试用 GLSL 做骨骼动画。对于每个骨骼,我有一个平移(x,y,z)和一个旋转(俯仰,滚动,偏航)(以度为单位)。我可以为每个骨骼构造一个 4x4 矩阵,但这会在着色器中占用大量寄存器空间,所以我只想存储每个骨骼的 6 个值,但我不知道如何做到这一点。

Nic*_*las 6

我不知道该怎么做是如何使用我拥有的旋转 vec3 旋转一个点。

很简单:不要。

Yaw-pitch-roll 是一种糟糕的方向编码方式,尤其是对于动画系统。改用四元数。它是 4 个值而不是 3 个,旋转的代码是众所周知的。

此外,它不需要像sin和这样的重量级操作cos

如果您想比较和对比所需的努力,请考虑数学。

给定一个四元数q,一个 position v,你需要这样做来旋转它:

vec3 temp = cross(q.xyz, v) + q.w * v;
vec3 rotated = v + 2.0*cross(q.xyz, temp);
Run Code Online (Sandbox Code Playgroud)

这是一个相当的数学。现在,考虑你必须为你的 YPR 案例做些什么,给定:

vec3 cosYPR = cos(ypr);
vec3 sinYPR = sin(ypr);
Run Code Online (Sandbox Code Playgroud)

这还不是全部。但这已经足够了。那是三个cos和三个sin操作。这些不是快速操作。仅此一项就可能需要整个四元数/矢量旋转计算的时间。但是在这样做之后,您现在必须进行多次乘法和相加才能计算 3x3 矩阵。然后,毕竟,你仍然需要做实际的矩阵乘法来旋转向量。

  • `vec3rotated = v + 2.0*cross(q.xyz, temp);` 不应该更有效(避免 1 DOT 和 1 MAD)?虽然不确定这是否需要单位季铵盐而你的不需要(但话说回来,谁使用非单位季铵盐进行旋转?)。 (3认同)
  • 你说‘sin’和‘cos’是重量级的。然而,我在网上看到一些人说它们在许多 GPU 上只是一个时钟周期。你能指出任何证据证明它们很慢吗? (2认同)