Skinning Mesh
이전 Static Mesh는 Vertex로 이루어진 Face를 이어 붙여 해당 Object의 World Matrix를 곱하여 출력을 하지만
Skinning Mesh는 조금 많이 다르다. 일단 Skinning Mesh의 Vertex는 영향을 받는 Bone의 가중치를 알고 있고 해당 가중치가 있는 Bone들의 World Matrix를 누적한 것과 Bone 기준 Vertex의 Offset Matrix를 연산하여 해당 Vertex의 World 값을 구한다.
Offset Matrix란 해당 Bone 기준 Vertex가 얼마나 떨어져 있는지 나타내는 Matrix이다. 이와 같이 가중치에 따라 연산을 하게 되면
Bone이 움직이면 Bone에 영향을 받는 Vertex들도 같이 움직이게 된다.
cbuffer cbSkinObject
{
float4x4 gSkinWorld : packoffset(c0);
float4x4 gSkinWorldView : packoffset(c4);
float4x4 gSkinWorldViewProj : packoffset(c8);
float4x4 gSkinTexTransform : packoffset(c12);
float4x4 gSkinShadowTransform : packoffset(c16);
float4x4 gSkinBoneTransforms[96] : packoffset(c20);
};
struct SkinVertexIn
{
uint4 BoneIndices1 : BONEINDICES1;
uint4 BoneIndices2 : BONEINDICES2;
float4 BoneWeights1 : WEIGHTS1;
float4 BoneWeights2 : WEIGHTS2;
float3 PosL : POSITION;
float2 Tex : TEXCOORD;
float3 NormalL : NORMAL;
float3 TangentL : TANGENT;
};
VertexOut Skin_VS(SkinVertexIn vin)
{
VertexOut vout;
float3 posL = float3(0.0f, 0.0f, 0.0f);
for (int i = 0; i < 4; ++i)
{
posL += vin.BoneWeights1[i] * mul(gSkinBoneTransforms[vin.BoneIndices1[i]], float4(vin.PosL, 1.0f)).xyz;
}
for (int j = 0; j < 4; ++j)
{
posL += vin.BoneWeights2[j] * mul(gSkinBoneTransforms[vin.BoneIndices2[j]], float4(vin.PosL, 1.0f)).xyz;
}
// 동차 공간 변환
vout.PosH = mul(gSkinWorldViewProj, float4(posL, 1.0f));
...
return vout;
};
Vertex Shader Input Layout에 해당 Vertex의 가중치와 Bone Index를 삽입하여 밀어 넣어준 후
해당 Bone의 Matrix를 기반으로 World 계산을 해준다.
'DirectX 11' 카테고리의 다른 글
[DirectX 11] Map / UnMap vs UpdataSubresource (0) | 2021.12.19 |
---|---|
[DirectX 11] Animation (0) | 2021.12.18 |
[DirectX 11] Normal Mapping (0) | 2021.12.18 |
[DirectX 11] Gamma Correction (0) | 2021.12.18 |
[DirectX 11] Deferred Rendering GBuffer (0) | 2021.12.14 |