Pre-transform bones with inverse bind instead of sending it to the shader
This commit is contained in:
parent
401fe22b75
commit
50dcc9cc1a
|
@ -227,7 +227,6 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat)
|
||||||
ShaderCode << "layout(std140) uniform BoneTransformBlock\n"
|
ShaderCode << "layout(std140) uniform BoneTransformBlock\n"
|
||||||
<< "{\n"
|
<< "{\n"
|
||||||
<< " mat4 BoneTransforms[100];\n"
|
<< " mat4 BoneTransforms[100];\n"
|
||||||
<< " mat4 InverseBindTransforms[100];\n"
|
|
||||||
<< "};\n"
|
<< "};\n"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
@ -260,11 +259,10 @@ bool CShaderGenerator::CreateVertexShader(const CMaterial& rkMat)
|
||||||
<< " \n"
|
<< " \n"
|
||||||
<< " if (BoneIdx > 0)\n"
|
<< " if (BoneIdx > 0)\n"
|
||||||
<< " {\n"
|
<< " {\n"
|
||||||
<< " mat4 BoneSpaceTransform = InverseBindTransforms[BoneIdx] * BoneTransforms[BoneIdx];\n"
|
<< " ModelSpacePos += vec3(vec4(RawPosition, 1) * BoneTransforms[BoneIdx] * Weight);\n";
|
||||||
<< " ModelSpacePos += vec3(vec4(RawPosition, 1) * BoneSpaceTransform * Weight);\n";
|
|
||||||
|
|
||||||
if (VtxDesc & eNormal)
|
if (VtxDesc & eNormal)
|
||||||
ShaderCode << " ModelSpaceNormal += RawNormal.xyz * inverse(transpose(mat3(BoneSpaceTransform))) * Weight;\n";
|
ShaderCode << " ModelSpaceNormal += RawNormal.xyz * inverse(transpose(mat3(BoneTransforms[BoneIdx]))) * Weight;\n";
|
||||||
|
|
||||||
ShaderCode << " }\n"
|
ShaderCode << " }\n"
|
||||||
<< " }\n"
|
<< " }\n"
|
||||||
|
|
|
@ -14,7 +14,6 @@ u32 CGraphics::mActiveContext = -1;
|
||||||
bool CGraphics::mInitialized = false;
|
bool CGraphics::mInitialized = false;
|
||||||
std::vector<CVertexArrayManager*> CGraphics::mVAMs;
|
std::vector<CVertexArrayManager*> CGraphics::mVAMs;
|
||||||
bool CGraphics::mIdentityBoneTransforms = false;
|
bool CGraphics::mIdentityBoneTransforms = false;
|
||||||
const CSkeleton *CGraphics::mpkCurrentSkeleton = nullptr;
|
|
||||||
|
|
||||||
CGraphics::SMVPBlock CGraphics::sMVPBlock;
|
CGraphics::SMVPBlock CGraphics::sMVPBlock;
|
||||||
CGraphics::SVertexBlock CGraphics::sVertexBlock;
|
CGraphics::SVertexBlock CGraphics::sVertexBlock;
|
||||||
|
@ -47,7 +46,7 @@ void CGraphics::Initialize()
|
||||||
mpVertexBlockBuffer = new CUniformBuffer(sizeof(sVertexBlock));
|
mpVertexBlockBuffer = new CUniformBuffer(sizeof(sVertexBlock));
|
||||||
mpPixelBlockBuffer = new CUniformBuffer(sizeof(sPixelBlock));
|
mpPixelBlockBuffer = new CUniformBuffer(sizeof(sPixelBlock));
|
||||||
mpLightBlockBuffer = new CUniformBuffer(sizeof(sLightBlock));
|
mpLightBlockBuffer = new CUniformBuffer(sizeof(sLightBlock));
|
||||||
mpBoneTransformBuffer = new CUniformBuffer(sizeof(CTransform4f) * 200);
|
mpBoneTransformBuffer = new CUniformBuffer(sizeof(CTransform4f) * 100);
|
||||||
|
|
||||||
sLightMode = eWorldLighting;
|
sLightMode = eWorldLighting;
|
||||||
sNumLights = 0;
|
sNumLights = 0;
|
||||||
|
@ -197,24 +196,13 @@ void CGraphics::LoadBoneTransforms(const CBoneTransformData& rkData)
|
||||||
mIdentityBoneTransforms = false;
|
mIdentityBoneTransforms = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGraphics::LoadBoneInverseBindTransforms(CSkeleton *pSkel)
|
|
||||||
{
|
|
||||||
if (mpkCurrentSkeleton != pSkel)
|
|
||||||
{
|
|
||||||
mpBoneTransformBuffer->BufferRange(pSkel->InverseBindMatricesData(), sizeof(CTransform4f) * 100, pSkel->InverseBindMatricesSize());
|
|
||||||
mpkCurrentSkeleton = pSkel;
|
|
||||||
mIdentityBoneTransforms = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGraphics::LoadIdentityBoneTransforms()
|
void CGraphics::LoadIdentityBoneTransforms()
|
||||||
{
|
{
|
||||||
static CTransform4f IdentityTransforms[200];
|
static const CTransform4f skIdentityTransforms[100];
|
||||||
|
|
||||||
if (!mIdentityBoneTransforms)
|
if (!mIdentityBoneTransforms)
|
||||||
{
|
{
|
||||||
mpBoneTransformBuffer->Buffer(&IdentityTransforms);
|
mpBoneTransformBuffer->Buffer(&skIdentityTransforms);
|
||||||
mpkCurrentSkeleton = nullptr;
|
|
||||||
mIdentityBoneTransforms = true;
|
mIdentityBoneTransforms = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,7 @@ class CGraphics
|
||||||
static u32 mActiveContext;
|
static u32 mActiveContext;
|
||||||
static bool mInitialized;
|
static bool mInitialized;
|
||||||
static std::vector<CVertexArrayManager*> mVAMs;
|
static std::vector<CVertexArrayManager*> mVAMs;
|
||||||
|
|
||||||
static bool mIdentityBoneTransforms;
|
static bool mIdentityBoneTransforms;
|
||||||
static const CSkeleton *mpkCurrentSkeleton;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// SMVPBlock
|
// SMVPBlock
|
||||||
|
@ -109,7 +107,6 @@ public:
|
||||||
static void SetupAmbientColor();
|
static void SetupAmbientColor();
|
||||||
static void SetIdentityMVP();
|
static void SetIdentityMVP();
|
||||||
static void LoadBoneTransforms(const CBoneTransformData& rkData);
|
static void LoadBoneTransforms(const CBoneTransformData& rkData);
|
||||||
static void LoadBoneInverseBindTransforms(CSkeleton *pSkel);
|
|
||||||
static void LoadIdentityBoneTransforms();
|
static void LoadIdentityBoneTransforms();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,13 @@ void CBone::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float
|
||||||
|
|
||||||
for (u32 iChild = 0; iChild < mChildren.size(); iChild++)
|
for (u32 iChild = 0; iChild < mChildren.size(); iChild++)
|
||||||
mChildren[iChild]->UpdateTransform(rData, pAnim, Time, AnchorRoot);
|
mChildren[iChild]->UpdateTransform(rData, pAnim, Time, AnchorRoot);
|
||||||
|
|
||||||
|
rTransform *= mInvBind;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
|
||||||
|
{
|
||||||
|
return rkData[mID] * AbsolutePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBone::IsRoot() const
|
bool CBone::IsRoot() const
|
||||||
|
@ -84,12 +91,12 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkDat
|
||||||
for (u32 iBone = 0; iBone < mBones.size(); iBone++)
|
for (u32 iBone = 0; iBone < mBones.size(); iBone++)
|
||||||
{
|
{
|
||||||
CBone *pBone = mBones[iBone];
|
CBone *pBone = mBones[iBone];
|
||||||
const CTransform4f& rkBoneTransform = rkData[pBone->ID()];
|
CVector3f BonePos = pBone->TransformedPosition(rkData);
|
||||||
|
|
||||||
// Draw bone
|
// Draw bone
|
||||||
CTransform4f Transform;
|
CTransform4f Transform;
|
||||||
Transform.Scale(skSphereRadius);
|
Transform.Scale(skSphereRadius);
|
||||||
Transform.Translate(rkBoneTransform.ExtractTranslation());
|
Transform.Translate(BonePos);
|
||||||
CGraphics::sMVPBlock.ModelMatrix = Transform;
|
CGraphics::sMVPBlock.ModelMatrix = Transform;
|
||||||
CGraphics::UpdateMVPBlock();
|
CGraphics::UpdateMVPBlock();
|
||||||
CDrawUtil::DrawSphere(CColor::skWhite);
|
CDrawUtil::DrawSphere(CColor::skWhite);
|
||||||
|
@ -100,8 +107,8 @@ void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkDat
|
||||||
|
|
||||||
for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
||||||
{
|
{
|
||||||
const CTransform4f& rkChildTransform = rkData[pBone->ChildByIndex(iChild)->ID()];
|
CVector3f ChildPos = pBone->ChildByIndex(iChild)->TransformedPosition(rkData);
|
||||||
CDrawUtil::DrawLine(rkBoneTransform.ExtractTranslation(), rkChildTransform.ExtractTranslation());
|
CDrawUtil::DrawLine(BonePos, ChildPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ class CSkeleton : public CResource
|
||||||
|
|
||||||
CBone *mpRootBone;
|
CBone *mpRootBone;
|
||||||
std::vector<CBone*> mBones;
|
std::vector<CBone*> mBones;
|
||||||
std::vector<CTransform4f> mInvBindMatrices;
|
|
||||||
|
|
||||||
static const float skSphereRadius;
|
static const float skSphereRadius;
|
||||||
|
|
||||||
|
@ -34,9 +33,6 @@ public:
|
||||||
std::pair<s32,float> RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData);
|
std::pair<s32,float> RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData);
|
||||||
|
|
||||||
inline u32 NumBones() const { return mBones.size(); }
|
inline u32 NumBones() const { return mBones.size(); }
|
||||||
inline const CTransform4f& BoneInverseBindMatrix(u32 BoneID) const { return mInvBindMatrices[BoneID]; }
|
|
||||||
inline const void* InverseBindMatricesData() const { return mInvBindMatrices.data(); }
|
|
||||||
inline u32 InverseBindMatricesSize() const { return mInvBindMatrices.size() * sizeof(CTransform4f); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBone
|
class CBone
|
||||||
|
@ -49,10 +45,12 @@ class CBone
|
||||||
u32 mID;
|
u32 mID;
|
||||||
CVector3f mPosition;
|
CVector3f mPosition;
|
||||||
TString mName;
|
TString mName;
|
||||||
|
CTransform4f mInvBind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CBone(CSkeleton *pSkel);
|
CBone(CSkeleton *pSkel);
|
||||||
void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot);
|
void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot);
|
||||||
|
CVector3f TransformedPosition(const CBoneTransformData& rkData) const;
|
||||||
bool IsRoot() const;
|
bool IsRoot() const;
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
|
@ -64,7 +62,6 @@ public:
|
||||||
inline CVector3f Position() const { return mPosition; }
|
inline CVector3f Position() const { return mPosition; }
|
||||||
inline CVector3f AbsolutePosition() const { return mPosition + (mpParent ? mpParent->AbsolutePosition() : CVector3f::skZero); }
|
inline CVector3f AbsolutePosition() const { return mPosition + (mpParent ? mpParent->AbsolutePosition() : CVector3f::skZero); }
|
||||||
inline TString Name() const { return mName; }
|
inline TString Name() const { return mName; }
|
||||||
inline const CTransform4f& InverseBindMtx() const { return mpSkeleton->BoneInverseBindMatrix(mID); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSKELETON_H
|
#endif // CSKELETON_H
|
||||||
|
|
|
@ -14,12 +14,10 @@ void CSkeletonLoader::SetLocalBoneCoords(CBone *pBone)
|
||||||
|
|
||||||
void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
||||||
{
|
{
|
||||||
mpSkeleton->mInvBindMatrices.resize(mpSkeleton->MaxBoneID() + 1);
|
|
||||||
|
|
||||||
for (u32 iBone = 0; iBone < mpSkeleton->mBones.size(); iBone++)
|
for (u32 iBone = 0; iBone < mpSkeleton->mBones.size(); iBone++)
|
||||||
{
|
{
|
||||||
CBone *pBone = mpSkeleton->mBones[iBone];
|
CBone *pBone = mpSkeleton->mBones[iBone];
|
||||||
mpSkeleton->mInvBindMatrices[pBone->ID()] = CTransform4f::TranslationMatrix(-pBone->AbsolutePosition());
|
pBone->mInvBind = CTransform4f::TranslationMatrix(-pBone->AbsolutePosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ void CCharacterNode::Draw(FRenderOptions Options, int ComponentIndex, const SVie
|
||||||
|
|
||||||
// Draw surface OR draw entire model
|
// Draw surface OR draw entire model
|
||||||
CGraphics::LoadBoneTransforms(mTransformData);
|
CGraphics::LoadBoneTransforms(mTransformData);
|
||||||
CGraphics::LoadBoneInverseBindTransforms(pSkel);
|
|
||||||
CModel *pModel = mpCharacter->NodeModel(mActiveCharSet);
|
CModel *pModel = mpCharacter->NodeModel(mActiveCharSet);
|
||||||
|
|
||||||
if (ComponentIndex < 0)
|
if (ComponentIndex < 0)
|
||||||
|
|
Loading…
Reference in New Issue