我最初使用 3 个表示对象原点、前向和向上方向的向量将对象原点和方向存储在 3D 空间中。
为了应用到模型视图矩阵堆栈的正确变换,我使用这三个向量组成仿射变换矩阵。
平移是微不足道的,但是通过构建正确的旋转矩阵(取决于旋转的角度和轴)并将其应用于这 3 个向量来应用旋转。
我将这种方法用于大量对象,并且旋转/仿射矩阵的组合导致了性能瓶颈。
我想知道是否有更明智/有效的方式来存储方向?
我最初使用 3 个表示对象原点、前向和向上方向的向量将对象原点和方向存储在 3D 空间中。
为了应用到模型视图矩阵堆栈的正确变换,我使用这三个向量组成仿射变换矩阵。
平移是微不足道的,但是通过构建正确的旋转矩阵(取决于旋转的角度和轴)并将其应用于这 3 个向量来应用旋转。
我将这种方法用于大量对象,并且旋转/仿射矩阵的组合导致了性能瓶颈。
我想知道是否有更明智/有效的方式来存储方向?
我最初使用 3 个表示对象原点、前向和向上方向的向量将对象原点和方向存储在 3D 空间中。
或者换句话说:您正在存储一个 3×3 矩阵。OpenGL 使用的矩阵是一样的,虽然它们是 4×4,但唯一的区别是,元素 4,4 总是 1,元素 0...3,4 都是 0,并且第一列 0,0...3 是 forward 和 up 的叉积,通常称为right。
这实际上是在 3D 空间中表示对象放置的最简洁和直接可访问的方式。您可以通过执行单个矩阵乘法来应用任何类型的转换。
另一种方法是使用四元数和偏移向量。但是,如果您希望您的对象是可翻译的,则必须将四元数转换为矩阵(或者您可以为转换层次结构链接许多平移/旋转配对,但使用矩阵实际上会导致更少的开销)。
除了内存,是什么阻止您存储整个 4x4 仿射矩阵?
更好的是,ISTR 表示,如果数组被标准化,底行通常是 [0, 0, 0, 1]
这样,您只需要存储前三行。
四元数可能是存储方向的最自然/最有效的方式(它在所有方面都应该比前向/向上向量更好)。四元数需要存储 4 个值,需要 10 次乘法和 15 次加法才能转换为 3x3 旋转矩阵——不需要除法或超越函数。
如果您特别需要空间,您可能只能使用 3 个值,因为您可以从其余三个稳健地生成单位四元数的第一个元素。这将需要额外的 3 次乘法、3 次加法和一个平方根(这也有点棘手,因为您需要确保第一个元素是非负的......)
在当前 GPGPU 上,四元数转换可能比 Matrix 更快,其中对全局内存的访问比对本地内存的访问要慢得多。根据此表,您计算了两倍,但需要获取不到一半的内存。
渲染将顶点着色器制服存储为本地内存,这里唯一合理的是使用矩阵。