1. 3D Direct Application
1.1 Character Animation
1.1.1 Blend Character Animation
1.1.1.1 Vertex Blending
- 골격에 입혀지는 표피의 정점들을 애니메이션하는 방법, 표피 정점들의 애니메이션을 위한 정점 혼합 알고리즘을 사용
- 골격 계통구조는 개별적인 뼈대들로 이루어지지만 골격에 입히는 표피 자체는 하나의 연속적인 메시임을 주의
- 표피의 한 정점에 둘 이상의 뼈대가 영향을 줄 수 있음
- 정점 최종 위치는 정점에 영향을 주는 뼈대들의 최종 변환들의 가중 평균에 의해 결정
- 이런 식으로 정점들을 혼합하면 관절 주변에서 정점들이 매끄럽게 전이되어 표피에 탄력이 있는 느낌을 줌
- 일반적으로 실제 응용에서 하나의 정점에 영향을 주는 뼈대는 최대 네 개
- 정점 혼합의 대상이 되는 캐릭터의 표피는 하나의 연속적인 메시, 메시의 각 정점마다 최대 네 개의 뼈대 Index를 가짐
- 각 Index는 최종 변환 행렬들의 배열의 한 원소를 가리킴, 그러한 배열을 뼈대 행렬 팔레트라고 부름
- 정점 혼합을 적용할 준비가 된 메시를 스키닝된 메시라고 부름, 법선과 접선도 비슷한 방식으로 변환
/* C++ 응용프로그램 */
struct PosNormalTexTanSkinned
{
XMFLOAT3 pos; XMFLOAT3 normal; XMFLOAT2 tex; XMFLOAT4 tangentU;
XMFLOAT3 weights; BYTE boneIndices[4];
};
/* Shader Code */
struct SkinnedVertexIn
{
float3 PosL : POSITION; float3 NormalL : NORMAL; float2 Tex : TEXCOORD; float4 TangentL : TANGENT;
float3 Weights : WEIGHTS; uint4 BoneIndices : BONEINDICES;
};
1.1.1.2 Vertex Shader
VertexOut SkinnedVS(SkinnedVertexIn vin)
- 정점 혼합을 수행하기 위한 가중치를 설정
float weights[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
weights[0] = vin.Weights.x; weights[1] = vin.Weights.y; weights[2] = vin.Weights.z;
weights[3] = 1.0f - weights[0] - weights[1] - weights[2];
- 정점 혼합을 수행, 법선 변환 시 변환 행렬에 비균등 비례가 없다고 가정하고 변환 행렬을 그대로 사용
float3 posL = float3(0.0f, 0.0f, 0.0f); float3 normalL = float3(0.0f, 0.0f, 0.0f); float3 tangentL = float3(0.0f, 0.0f, 0.0f);
for (int i = 0; i < 4; ++i)
{
posL += weights[i] * mul(float4(vin.PosL, 1.0f), gBoneTransforms[vin.BoneIndices[i]]).xyz;
normalL += weights[i] * mul(vin.NormalL, (float3x3) gBoneTransforms[vin.BoneIndices[i]]);
tangentL += weights[i] * mul(vin.TangentL.xyz, (float3x3) gBoneTransforms[vin.BoneIndices[i]]);
}
- 세계 공간으로 변환하고 동차 절단 공간으로 변환
vout.PosW = mul(float4(posL, 1.0f), gWorld).xyz;
vout.NormalW = mul(normalL, (float3x3) gWorldInvTranspose);
vout.TangentW = float4(mul(tangentL, (float3x3) gWorld), vin.TangentL.w);
vout.PosH = mul(float4(posL, 1.0f), gWorldViewProj);
vout.Tex = mul(float4(vin.Tex, 0.0f, 1.0f), gTexTransform).xy;
vout.ShadowPosH = mul(float4(posL, 1.0f), gShadowTransform);
1.1.2 M3D File
1.1.2.1 Skinning Vertex
void M3DLoader::ReadSkinnedVertices(std::ifstream& fin, uint32 numVertices,
std::vector<Vertex::PosNormalTexTanSkinned>& vertices)
- 새로 추가된 혼합 가중치들과 뼈대 Index들을 포함하는 정점 자료
- 이러한 변화를 반영해서 스키닝된 메시의 정점 자료를 적재
Position: ... Tangent: ... Normal: ... Tex-Coords: ... BlendWeight: ... BlendIndeices: ...
Position: ... Tangent: ... Normal: ... Tex-Coords: ... BlendWeight: ... BlendIndeices: ...
...
1.1.2.2 Bone Offset
void M3DLoader::ReadBoneOffsets(std::ifstream& fin, uint32 numBones,
std::vector<XMFLOAT4X4>& boneOffsets)
- 각 뼈대당 하나씩의 오프셋 변환 행렬을 담음
BoneOffset0 ...
BoneOffset1 ...
...
1.1.2.3 Bone Hierarchy
void M3DLoader::ReadBoneHierarchy(std::ifstream& fin, uint32 numBones,
std::vector<int32>& boneIndexToParentIndex)
- 계통구조 배열, 즉 i번째 원소가 i번째 뼈대의 부모 Index를 담고 있는 정수 배열을 저장
ParentlndexOfBoneO: -1
ParentlndexOfBone1: 0
ParentlndexOfBone2: 1
...
1.1.2.3 Animation Clip & Bone Key Frame
void M3DLoader::ReadAnimationClips(std::ifstream& fin, uint32 numBones,
uint32 numAnimationClips, std::map<std::string, AnimationClip>& animations)
void M3DLoader::ReadBoneKeyframes(std::ifstream& fin, uint32 numBones, BoneAnimation& boneAnimation)
- 각 애니메이션 클립 자료는 사람이 읽기 편한 이름과 골격의 각 뼈대의 키 프레임 목록으로 구성
- 키 프레임 목록의 각 키 프레임은 시작 시간, 뼈대의 위치를 지정하는 이동 벡터, 뼈대의 축척을 지정하는 비례 벡터, 뼈대의 방향을 지정하는 사원수로 구성
AnimationClip run_loop
{
BoneO #Keyframes: 18
{
Time: 0 Pos: 2.538344 101.6727 -0.52932
Scale: 1 1 1
Quat: 0.4042651 0.3919331 -0.5853591 0.5833637
Time: 0.0666666 Pos: 0.81979 109.6893 -1.575387
Scale: 0.9999998 0.9999998 0.9999998
Quat: 0.4460441 0.3467651 -0.5356012 0.6276384
...
}
...
}
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 48. 3D Direct Application - Character Animation #3 (0) | 2023.07.04 |
---|---|
[Direct11] 46. 3D Direct Application - Character Animation #1 (0) | 2023.07.04 |
[Direct11] 45. 3D Direct Application - Mesh Basic Model (0) | 2023.07.04 |
[Direct11] 44. 3D Direct Application - Shadow Mapping #2 (0) | 2023.07.03 |
[Direct11] 43. 3D Direct Application - Shadow Mapping #1 (0) | 2023.07.03 |