API 不可知 row/colum-major 矩阵表示
API agnostic row/colum-major matrix representation
因为在D3D/HLSL中我们使用行向量(1xN matrices
)因此预乘(vector * matrix
),我们将翻译部分存储在矩阵的第4行:
m00 m01 m02 0
m10 m11 m12 0
m20 m21 m22 0
Tx Ty Tz 1
所以变换后的x
坐标是x' = x*m00 + y*m10 + z*m20 + 1*Tx
。如果矩阵仅包含翻译,则它会翻译成 x' = x*1 + 1*Tx = x + Tx
.
基于HLSL docs和以往的一些实验,统一矩阵是按列加载的,所以一个寄存器会包含{m00,m10,m20,m30}
。这对向量矩阵乘法很有用,因为它转换为 4 个点积 (x' = vec-registry dot mat-registry_0
),可能只有一条硬件指令。
另一方面,OGL/GLSL 使用列向量和 post 乘法,这意味着翻译部分改为存储在第 4 列(上面矩阵的转置)。 Based on the wiki“GLSL 矩阵总是列优先”。
一些要点:
- 在矩阵运算的 CPU 一侧,我想将它们矢量化
- 这意味着内存布局很重要,因此可以快速将适当的列加载到注册表中
- 目前我的矩阵按列
{m00,m10,m20,m30,m01,...,m33}
存储,其中 m30,m31,m32
存储翻译部分(我使用行向量 -> 预乘)
- 此外,我想使用相同的内存布局将统一数据传递给图形 API(memcpy 到缓冲区而不转置矩阵)
- 我检查了 UE4 的 Matrix 实现,我看不到任何基于底层渲染的分离 API(这是预期的结果)
以 API 不可知的方式处理这些差异的最佳方法是什么?
我想我可以保留我当前的矩阵实现(DX 样式、行向量、预乘、SSE 的列主存储)并在 GLSL 代码中设置 row_major layout
所以它以相反的方式读取数据。如果确实有效,这对性能有何影响(如果有)?
主要目标平台是 Vulkan 和 D3D11/12。
两个 API 都针对相同的 GPU,因此您可以合理地确定矩阵布局对那里的性能无关紧要。就此而言,如果需要,Vulkan 可以使用 HLSL。
因为在D3D/HLSL中我们使用行向量(1xN matrices
)因此预乘(vector * matrix
),我们将翻译部分存储在矩阵的第4行:
m00 m01 m02 0
m10 m11 m12 0
m20 m21 m22 0
Tx Ty Tz 1
所以变换后的x
坐标是x' = x*m00 + y*m10 + z*m20 + 1*Tx
。如果矩阵仅包含翻译,则它会翻译成 x' = x*1 + 1*Tx = x + Tx
.
基于HLSL docs和以往的一些实验,统一矩阵是按列加载的,所以一个寄存器会包含{m00,m10,m20,m30}
。这对向量矩阵乘法很有用,因为它转换为 4 个点积 (x' = vec-registry dot mat-registry_0
),可能只有一条硬件指令。
另一方面,OGL/GLSL 使用列向量和 post 乘法,这意味着翻译部分改为存储在第 4 列(上面矩阵的转置)。 Based on the wiki“GLSL 矩阵总是列优先”。
一些要点:
- 在矩阵运算的 CPU 一侧,我想将它们矢量化
- 这意味着内存布局很重要,因此可以快速将适当的列加载到注册表中
- 目前我的矩阵按列
{m00,m10,m20,m30,m01,...,m33}
存储,其中m30,m31,m32
存储翻译部分(我使用行向量 -> 预乘) - 此外,我想使用相同的内存布局将统一数据传递给图形 API(memcpy 到缓冲区而不转置矩阵)
- 我检查了 UE4 的 Matrix 实现,我看不到任何基于底层渲染的分离 API(这是预期的结果)
以 API 不可知的方式处理这些差异的最佳方法是什么?
我想我可以保留我当前的矩阵实现(DX 样式、行向量、预乘、SSE 的列主存储)并在 GLSL 代码中设置 row_major layout
所以它以相反的方式读取数据。如果确实有效,这对性能有何影响(如果有)?
主要目标平台是 Vulkan 和 D3D11/12。
两个 API 都针对相同的 GPU,因此您可以合理地确定矩阵布局对那里的性能无关紧要。就此而言,如果需要,Vulkan 可以使用 HLSL。