DirectX 11世界变换异常:添加平移缩放后立方体渲染出错
问题描述
我尝试在世界空间中渲染立方体:
- 当传入的World XMMatrix为单位矩阵时,立方体可正常渲染(正常效果:立方体完整显示,各面比例、位置均正常)
- 但为世界矩阵添加平移和缩放因子后,出现渲染异常(异常效果:立方体形状扭曲,显示错乱)
相关代码片段:
TRANSFORM.CPP
m_position = { 0.0f,0.0f,0.0f }; m_scale = { 1.0f,1.0f,1.0f }; DirectX::XMStoreFloat4x4(&m_matrix_translation , DirectX::XMMatrixTranslation(m_position.x, m_position.y, m_position.z)); DirectX::XMStoreFloat4x4(&m_matrix_scalar,DirectX::XMMatrixScaling(m_scale.x, m_scale.y, m_scale.z));
RENDER.CPP
DirectX::XMMATRIX view = gp_MainCameraH->GetXM_View(); DirectX::XMMATRIX world = GetXM_Scalar() * GetXM_Translation(); // 如果这里用单位矩阵,立方体渲染正常 DirectX::XMMATRIX proj = gp_MainCameraH->GetXM_Projection(); DirectX::XMMATRIX vp = view * proj; DirectX::XMMATRIX wvp = world * vp; // 设置着色器常量缓冲区 RenderStateManager::GetEffectVariable("gWorldViewProj")->SetMatrix(reinterpret_cast<float*>(&(wvp)));
问题根源与解决方案
嘿,我一眼就瞅出来核心问题是矩阵乘法顺序搞反了!咱们一步步来解决:
1. 为啥顺序错了会出问题?
在DirectX的HLSL着色器中,默认采用列向量左乘矩阵的方式进行顶点变换(即 最终顶点 = 变换矩阵 × 原始顶点)。而顶点变换的逻辑是:先做世界变换,再视图变换,最后投影变换。由于矩阵乘法不满足交换律,对应的组合矩阵顺序必须是投影矩阵 → 视图矩阵 → 世界矩阵,和变换逻辑的顺序完全相反。
你当前的代码把WVP矩阵算成了 world × view × proj,完全颠倒了正确顺序,导致变换逻辑混乱,自然渲染出扭曲的立方体。
2. 修正矩阵计算顺序
把WVP矩阵的计算代码改成正确的顺序即可:
// 正确的WVP矩阵顺序:投影 × 视图 × 世界 DirectX::XMMATRIX wvp = proj * view * world;
3. 验证着色器中的变换代码
顺便确认你的HLSL着色器里的顶点变换代码是如下列向量左乘的形式(这是DirectX默认的写法):
float4 finalPos = mul(gWorldViewProj, float4(vertexPosition, 1.0f));
如果你的着色器用的是行向量右乘(float4 finalPos = mul(float4(vertexPosition,1.0f), gWorldViewProj);),那CPU端的矩阵顺序需要是 world × view × proj,但从你的异常效果来看,大概率是着色器用了默认的列向量左乘,所以改CPU端的矩阵顺序就好。
4. 确认缩放平移顺序(你这部分是对的)
你当前用 GetXM_Scalar() * GetXM_Translation() 的顺序是正确的——先缩放再平移,这样缩放不会影响平移的距离。如果反过来,平移向量会被缩放,导致位置偏移异常,这部分不用改~
改完之后再测试,平移和缩放后的立方体应该就能正常显示啦!
内容的提问来源于stack exchange,提问作者Tesla

