728x90
저번에 만들었던 선형보간의 개량이다.
선형보간 시, Buffer에 데이터를 넘긴 후, 처리하는 방법이 있고,
데이터를 Device에서 처리 후 Buffer에 넘기는 방법이 있는데,
전에 만들었던 방법은, 데이터를 넘기기 전 Device에서 처리 후, Buffer에 넘기는것 이었는데,
이번에 한 방법은 Buffer에 데이터를 다 때려박은 후 DeviceContext에서 데이터를 처리하는 방법이다.
Buffer를 수정한다.
// Frame 구조체: 애니메이션 재생에 사용되는 프레임 정보를 저장하는 구조체
struct Frame
{
int clip = 0; // 현재 재생 중인 클립의 인덱스
int curFrame = 0; // 현재 프레임 인덱스
float time = 0.0f; // 현재 프레임에서의 경과 시간
float scale = 1.0f; // 애니메이션 재생 속도 조절용 스케일
};
struct Motion
{
float takeTime = 0.2f;
float tweenTime = 0.0f;
float runningTime = 0.0f;
float padding;
Frame cur, next;
Motion()
{
next.clip = -1.0f;
}
};
// FrameBuffer 클래스: 상속된 ConstBuffer를 사용하여 프레임 데이터를 GPU에 전달하는 클래스
class FrameBuffer : public ConstBuffer
{
public:
FrameBuffer() : ConstBuffer(&motion, sizeof(Motion)) {}; // 프레임 데이터를 상속된 ConstBuffer에 전달
Motion* GetData() { return &motion; } // 프레임 데이터에 대한 포인터 반환
private:
Motion motion; // 프레임 데이터를 저장하는 구조체 인스턴스
};
Buffer값을 수정해서, 한개의 구조채를 새롭게 만들고, 전 프레임과 이후 프레임으로 나누어, 버퍼를 전달하게 한다.
struct Frame
{
int clip;
int curFrame;
float time;
float scale; // 애니메이션 재생 속도 조절용 스케일
};
struct Motion
{
float takeTime; // 보간시간
float tweenTime; // 계산 시간
float running_time;
float padding;
Frame cur, next;
};
위와같이 버퍼구조체를 다시 만든다.
// 'SkinWorld' 함수 정의: float4 형식의 'indices'와 'weights' 매개변수를 받음
matrix SkinWorld(float4 indices, float4 weights)
{
// 결과 변환 행렬을 0으로 초기화
matrix transform = 0;
matrix nextTransform = 0;
// 현재와 다음 애니메이션 프레임을 위한 행렬 선언
matrix cur, next;
// 시간 보간을 적용한 현재와 다음 애니메이션 프레임을 위한 행렬 선언
matrix curAnim, nextAnim;
// 현재와 다음 애니메이션 프레임의 구성 요소를 위한 float4 벡터 선언
float4 c0, c1, c2, c3;
float4 n0, n1, n2, n3;
// 각 본에 대해 반복 (최적화를 위한 언롤 루프)
[unroll(4)]
for (int i = 0; i < 4; i++)
{
// 모션 데이터에서 현재 클립 및 프레임 정보를 가져옴
int clip = motion.cur.clip;
int curFrame = motion.cur.curFrame;
// 텍스처에서 현재 애니메이션 프레임의 변환 행렬 구성 요소를 로드
c0 = transformMap.Load(int4(indices[i] * 4 + 0, curFrame, clip, 0));
c1 = transformMap.Load(int4(indices[i] * 4 + 1, curFrame, clip, 0));
c2 = transformMap.Load(int4(indices[i] * 4 + 2, curFrame, clip, 0));
c3 = transformMap.Load(int4(indices[i] * 4 + 3, curFrame, clip, 0));
// 현재 애니메이션 프레임의 행렬 생성
cur = matrix(c0, c1, c2, c3);
// 다음 프레임의 변환 행렬 구성 요소 로드
n0 = transformMap.Load(int4(indices[i] * 4 + 0, curFrame + 1, clip, 0));
n1 = transformMap.Load(int4(indices[i] * 4 + 1, curFrame + 1, clip, 0));
n2 = transformMap.Load(int4(indices[i] * 4 + 2, curFrame + 1, clip, 0));
n3 = transformMap.Load(int4(indices[i] * 4 + 3, curFrame + 1, clip, 0));
// 다음 프레임의 행렬 생성
next = matrix(n0, n1, n2, n3);
// 현재와 다음 프레임을 시간에 따라 보간하여 현재 애니메이션 행렬 생성
curAnim = lerp(cur, next, motion.cur.time);
transform += mul(weights[i], curAnim);
}
if (motion.next.clip <= -1)
return transform;
// 모션의 다음 클립 및 프레임 정보를 가져옴
[unroll(4)]
for (int i = 0; i < 4; i++)
{
int clip = motion.next.clip;
int curFrame = motion.next.curFrame;
// 클립이 유효한 경우에만 실행되는 조건문
// 다시 다음 클립의 현재 및 다음 프레임의 변환 행렬 구성 요소 로드
c0 = transformMap.Load(int4(indices[i] * 4 + 0, curFrame, clip, 0));
c1 = transformMap.Load(int4(indices[i] * 4 + 1, curFrame, clip, 0));
c2 = transformMap.Load(int4(indices[i] * 4 + 2, curFrame, clip, 0));
c3 = transformMap.Load(int4(indices[i] * 4 + 3, curFrame, clip, 0));
// 다시 현재 및 다음 프레임의 행렬 생성
cur = matrix(c0, c1, c2, c3);
n0 = transformMap.Load(int4(indices[i] * 4 + 0, curFrame + 1, clip, 0));
n1 = transformMap.Load(int4(indices[i] * 4 + 1, curFrame + 1, clip, 0));
n2 = transformMap.Load(int4(indices[i] * 4 + 2, curFrame + 1, clip, 0));
n3 = transformMap.Load(int4(indices[i] * 4 + 3, curFrame + 1, clip, 0));
// 다음 프레임의 행렬 생성
next = matrix(n0, n1, n2, n3);
// 현재와 다음 애니메이션 행렬을 tweenTime에 따라 보간하여 최종 애니메이션 행렬 생성
nextAnim = lerp(cur, next, motion.next.time);
// 가중치를 곱하여 결과 행렬에 더함
nextTransform += mul(weights[i], nextAnim);
}
// 최종 결과 행렬 반환
return lerp(transform, nextTransform, motion.tweenTime);
}
그리고. 행렬데이터를 재정립하면 끝.
728x90
'서울게임아카데미 교육과정 6개월 국비과정' 카테고리의 다른 글
20231123 36일차 3인칭 카메라 구현 (0) | 2023.11.24 |
---|---|
20231122 35일차 애니메이션 프레임간 자동전환 (0) | 2023.11.23 |
20231117 33일차 모델의 애니메이션 리깅출력하기 (0) | 2023.11.17 |
20231116 32일차 모델의 애니메이션 리깅저장하기1 (0) | 2023.11.16 |
20231115 31일차 모델의 본위치 받아와서 사용하기 (0) | 2023.11.15 |