【问题标题】:Why is this Transpose() required in my WorldViewProj matrix?为什么我的 WorldViewProj 矩阵中需要这个 Transpose()?
【发布时间】:2015-11-09 08:04:15
【问题描述】:

给定一个超基本的顶点着色器,例如:

output.position = mul(position, _gWorldViewProj);

我遇到了很多麻烦,因为我将 _gWorldViewProj 设置如下;我尝试了两者(有点甩尾)以确保它不只是倒退。

mWorldViewProj = world * view * proj;
mWorldViewProj = proj * view * world;

我的解决方案原来是:

mWorldView = mWorld * mView;
mWorldViewProj = XMMatrixTranspose(worldView * proj);

有人可以解释为什么需要这个 XMMatrixTranspose 吗?我知道 XNA 和 HLSL(我认为)之间存在矩阵差异,但原版 C++ 和 HLSL 之间没有,尽管我可能是错的。

问题是我不知道是我错了还是我错了什么!所以如果有人能准确地告诉我为什么需要转置,我希望不会再犯同样的错误。

【问题讨论】:

  • 你能解释一下是什么症状让你相信你需要转置矩阵吗?

标签: matrix direct3d matrix-multiplication hlsl


【解决方案1】:

在 CPU 上,二维数组通常以行优先顺序存储,因此内存中的顺序为 x[0][0]x[0][1]、... 在 HLSL 中,矩阵声明默认为 column-major ordering,因此顺序为x[0][0], x[1][0], ...

为了将内存从 CPU 上定义的格式转换为 HLSL 中预期的顺序,您需要在将 CPU 矩阵发送到 GPU 之前对其进行转置。或者,您可以在 HLSL 中使用 row_major 关键字将矩阵声明为主要行,从而无需转置,但会导致 HLSL 中出现不同的代码生成(您通常会使用 mul-adds 而不是点积)。

【讨论】:

  • 所以说每当我使用 XMMATRIX 并将其存储在 float4x4 常量缓冲区中时,我总是需要先转置它是否正确?
  • @Dave 通常,但不一定。按照惯例,大多数数学库(例如 XNAMath / DirectXMath)将生成行优先矩阵数据,因此当库生成投影矩阵时,它将是行优先的并且需要转置。但是您也可以以列主要格式输出库,从而无需转置。请记住,在上传到常量缓冲区之前,您最多只需要一次转置操作 - 不要在 CPU 上转置中间矩阵。
  • HLSL 不需要它,它只是默认为列优先。这在Working with D3DXMath 部分的DirectXMath 程序员指南 中有明确介绍,该部分位于将 DirectXMath 与 Direct3D 结合使用以及指向相关HLSL docs 的链接。简而言之:DirectXMath 支持左手或右手查看坐标,但所有矩阵都是行优先的。您可以告诉 HLSL 使用 row-major,但它默认为 column-major,这会稍微快一些。因此,在设置 CB 之前进行转置。
猜你喜欢
  • 2012-08-24
  • 2012-10-28
  • 2022-12-13
  • 1970-01-01
  • 2021-10-26
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多