Programming/D3D12

[책공부] 캐릭터 애니메이션 chap 23 (연습 문제 X)

Dorasima 2024. 3. 25. 11:44

(사실 이해했는지 모르겠다. 어렴풋이 느껴질 뿐... 그래도 그 느낌을 정리한다.)

1. 캐릭터 애니메이션

- 책 내용은 그냥  '그렇구나' 라는 생각을 하며 읽을 수 있다. 예제 또한 읽기 쉽게 특수 제작된 모델 형식과, 애니메이션을 가지고 연습할 수 있도록 도와준다. 그냥 책에서 정해준 구조에, 정해준 방법으로 따라만했다.. 

- 블로그에는 책에 소개된 개념과, 그 개념을 예제에서는 어떤방식으로 구현했는지 간단하게 언급하고 넘어갈 것이다. 

 

- 이걸로 느낌을 잡았으니, 다음은 FBX, OBJ 같은 상용 포멧을 나만의 Render위에 올려봐야 제대로 공부가 끝날 것이다.

 

2. 뼈대(bone) 좌표계와 위계구조(Hierarchy)

- 언리얼 마네킹이나 블랜더에서 모델을 하나 만들면, Pelvis나 Root에서 bone들이 부모 자식 관계를 가지고, 부모가 자식의 이전 단계 좌표계 역할을 한다. 그리고 그 위에 Mesh로 피부, 옷 등이 표현되어 있다.

- Rendering Tick에서는 캐릭터의 모든 bone이 자기의 좌표계 위에서 Transform을 계산하여서 본인의 World 위치를 가지게 되는 것이다.

(해당 bone 로컬변환 * 부모좌표 변환 * 부모의 부모좌표 변환 * .... * 부모의 부모의 ... 부모좌표 변환 * ... * Root좌표 변환)

 

- 예제에서는 자식 element 값이 부모 index 값을 가지는 배열로 그 위계를 표현하였다. Tick 마다 이 배열에 있는 모든 bone에 대해서 본인 Transform 계산 * 뿌리까지 넘어가는 좌표변환 Transform 계산을 해주는데, 메모이제이션(memoization) 방식을 이용해서 어떤 bone의 Transform계산을 할 때가 되면, 그 부모의 Root 까지의 Transform은 이미 계산이 되어있는 구조로 만들어, 중복 계산을 피했다.

 

3. 매시 스키닝 (Mesh Skinning)

- 3d 모델은 bone들이 서로 위계를 가지며 존재하고, 그 위를 덮는 Mesh가 있다.

이것을 bone Transfrom과 함께 움직이게(animation) 해야 한다.

 

- 이걸 위해서 모델 파일에는 (예제 파일에 관한 내용이다. 다른 상용 포멧은 그때가서 알아보겠다.)

- Mesh Vertex 정보에 움직임을 따라갈 bone의 index 정보와 그 가중치를 가지고 있고

- Mesh가 원래 모델에서 Root를 기준으로 위치하는 Offset 값이 있을 것이다.

 

- 일단 Mesh의 기존 Offset 값을 Root 기준 좌표계에서 Mesh에 영향을 주는 bone 기준 좌표계로 옮겨야한다. 

- 그렇게 해야, 해당 bone이 부모 변환( ~  Root 변환)을 타고 움직이고, Mesh위의 Vertex은 해당 bone의 변환을 타고 움직여서 계산이 훨씬 간편하기 때문이다.

 

-  Mesh 위에 한 점이, bone 하나에만 연결이 된다면, 마인크래프트 스티브 처럼 보일 것이다. 그래서 하나의 Vertex에도 여러개의 bones의 변환을 가중치 별로 나눠 받아 움직임을 표현하게 된다. 이것을 Vertex Blending 이라고 한다.

- 예제에서는 한 Vertex당 최대 4개의 bone의 영향을 받도록 하였다.

 

5. 어쨌든 파일을 형식에 맞게 제대로 읽어서 깔끔한 구조위에 올리는게 핵심 과제

- ... 이제 직접해봐야 한다.

 

6. 예제에서 사용한 방법

(파일을 읽고난 다음에)

6.1 앱

- 스키닝 하는 모델을 나타내는 구조체를 생성한다.

- 구조체 맴버로는 : Skin Mesh 데이터 구조체, 최종 bone의 위치, 애니메이션 메타정보, (애니메이션 용 시간)을 가진다.

 

- Skin Mesh 데이터 구조체 맴버로는 : Bone의 위계구조를 나타내는 배열, Mesh가 참조하게 될 Offset 데이터, 애니메이션 딕셔너리를 가진다.

- 항목 2번의 내용처럼 각 bone마다 위계 구조로 인한 좌표계 변환 + 이전글과 연관이 있는  keyframe 간 구면 선형 보간을 이용하여 캐릭터의 보든 bones들을 현재 time에 맞춰 최종 위치를 정한다. (애니메이션)

 

6.2 쉐이더

- 메쉬를 나타내는 Vertices를 IA로 받고, 해당 프레임의 최종 bone의 위치는 Constants Buffer로 받는다.

- Vertex 정보에 있는 bone Index 값으로 CB에서 bone 기준 최종 world 좌표 변환을 한다.

 

6.3 텍스쳐 정보, 머테리얼 정보, Sub geo 정보도 모델링 파일안에 정보로 존재한다

- 이를 알맞은 구조를 만들어서 App위에 올리고 사용해야 한다.

 

 

7. 연습문제

(연습 문제는 안 풀었습니다. 하드 코딩으로 로봇을 만들어서 움직여보라길래... )

 

8. 메모용

- bad_alloc 문제 : View Heap에 View가 이상하게 올라가져 있으면 device hung으로 터진다. 

 

더보기

책 : DirectX 12를 이용한 3D 게임 프로그래밍 입문