完成自己的shader系統后,翻出之前寫過的代碼中發現有一個地方很奇怪
我的矩陣定義跟OGRE的沒什么區別
union
{
struct
{
float m11, m12, m13, m14;
float m21, m22, m23, m24;
float m31, m32, m33, m34;
float m41, m42, m43, m44;
};
float m[4][4];
};
乘法也跟OGRE的一模一樣,但在將view及project乘好的矩陣送給HLSL時,卻必須轉置下,才能得到正確的結果
mSkinnedEffect.mMatrix.mValue = (camera.mViewMatrix * camera.mProjectMatrix).Transpose();
shader:
float4 localpos = mul(In.Position, skinTransform);
OGRE中有這么一段代碼及注釋:
const Matrix4& AutoParamDataSource::getProjectionMatrix(void) const
{
if (mProjMatrixDirty)
{
// NB use API-independent projection matrix since GPU programs
// bypass the API-specific handedness and use right-handed coords
if (mCurrentRenderable && mCurrentRenderable->getUseIdentityProjection())
{
// Use identity projection matrix, still need to take RS depth into account.
RenderSystem* rs = Root::getSingleton().getRenderSystem();
rs->_convertProjectionMatrix(Matrix4::IDENTITY, mProjectionMatrix, true);
}
else
{
mProjectionMatrix = mCurrentCamera->getProjectionMatrixWithRSDepth();
}
if (mCurrentRenderTarget && mCurrentRenderTarget->requiresTextureFlipping())
{
// Because we're not using setProjectionMatrix, this needs to be done here
// Invert transformed y
mProjectionMatrix[1][0] = -mProjectionMatrix[1][0];
mProjectionMatrix[1][1] = -mProjectionMatrix[1][1];
mProjectionMatrix[1][2] = -mProjectionMatrix[1][2];
mProjectionMatrix[1][3] = -mProjectionMatrix[1][3];
}
mProjMatrixDirty = false;
}
return mProjectionMatrix;
}
貌似是跟左右手這個惡心的東西有關系
回看DirectXSDK中提供的BasicHLSL例子
mWorld = g_mCenterWorld * *g_Camera.GetWorldMatrix();
mProj = *g_Camera.GetProjMatrix();
mView = *g_Camera.GetViewMatrix();
mWorldViewProjection = mWorld * mView * mProj;
V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
shader:
Output.Position = mul(vAnimatedPos, g_mWorldViewProjection);
絲毫無需轉置矩陣,Effect接口中也提供有SetMatrixTranspose這類方法。所以排除內部有自動轉置的嫌疑。
詢問過野豬這個問題,野豬答曰:"轉置后傳輸至需要傳3個vector, 最后一個是[0 0 0 1]”
有達人知道的,可以指點下迷津 :)