完成自己的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]”
有达人知道的,可以指点下迷津 :)