행렬(Matrix) 스터디 - 실습 및 SimpleMath for DirectXMath
DirectX 행렬식 계산 편의를 위해 DirectXTK 의 DirectXMath 랩핑 모듈이 필요. SimpleMath.h/.cpp/.iln 파일들. 아래에서 다운로드 받을 수 있음.
SimpleMath.h 를 보면 아래와 같이랩핑한 DirectX 하위 클래스들을 확인할 수 있음. 여기서 Vector 시리즈와 Matrix 가 앞에서 학습한 행렬 수식과 관련된 클래스들.
Matrix 메소드를 보면 앞에서 다뤘던 역행렬, 전치, Translation, Scale, Rotation 행렬 생성 시리즈들을 모두 볼 수 있음.
해당 함수의 구현부를 가면 ~\Windows Kits\10\Include\10.0.19041.0\um\DirectXMathMatrix.inl 경로의 DX 구현부 함수가 호출되는 것을 확인할 수 있음.
다음은 기존 코드에서 상수버퍼에 matrix 를 전달해서 갱신하는 작업.
먼저 Types.h 헤더에 DirectX::SimpleMath 네임스페이스의 타입을 사용하도록 수정.
// 기존 using 선언
//using Vec2 = DirectX::XMFLOAT2;
//using Vec3 = DirectX::XMFLOAT3;
//using Vec4 = DirectX::XMFLOAT4;
// SimpleMath 타입들로 교체
using Vec2 = DirectX::SimpleMath::Vector2;
using Vec3 = DirectX::SimpleMath::Vector3;
using Vec4 = DirectX::SimpleMath::Vector4;
using Matrix = DirectX::SimpleMath::Matrix;
Update() 단에서 상수버퍼(Constant Buffer)에 넘길 TransformData 구조체 선언을 수정하고 갱신 처리. TransformData 의 값을 Matrix World, View, Projection 으로 수정.
Update() 함수에서는 새로 만든 3개 벡터 localPosition, localRotation, localScale 을 SimpleMath 유틸리티 함수를 이용해서 Matrix 로 변환. Matrix 곱셈 연산을 통해 World 변환 Matrix 를 만들어서 최종적으로 TransformData 인자로 전달.
struct TransformData
{
Matrix matWorld = Matrix::Identity;
Matrix matView = Matrix::Identity;
Matrix matProjection = Matrix::Identity;
};
void Game::Update()
{
Matrix matScale = Matrix::CreateScale(_localScale);
Matrix matRotation = Matrix::CreateRotationX(_localRotation.x);
matRotation *= Matrix::CreateRotationY(_localRotation.y);
matRotation *= Matrix::CreateRotationZ(_localRotation.z);
Matrix matTranslation = Matrix::CreateTranslation(_localPosition);
Matrix matWorld = matScale * matRotation * matTranslation; // SRT
_transformData.matWorld = matWorld;
D3D11_MAPPED_SUBRESOURCE subResource;
ZeroMemory(&subResource, sizeof(subResource));
_deviceContext->Map(_constantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &subResource);
::memcpy(subResource.pData, &_transformData, sizeof(_transformData));
_deviceContext->Unmap(_constantBuffer.Get(), 0);
}
마지막으로, VertexShader 에서 전달받은 상수버퍼의 값을 연산해서 VS_OUTPUT 으로 return 처리하면 행렬 연산으로 WVP 연산 과정 완료.
여기까지 실습까지 마쳤고, 다음 단계는 앞에서 다뤄봤던 DirectX 핵심 요소들과 행렬 연산 등의 구조를 설계해서 구조화 하는 단계.
DirectX Tool Kit (DirectXTK)
https://github.com/microsoft/DirectXTK
<리얼-타임 렌더링(REAL-TIME RENDERING) 4/e> 구입 링크
https://link.coupang.com/a/8VWas
<DirectX 12를 이용한 3D 게임 프로그래밍 입문> 구입 링크
https://link.coupang.com/a/8V4Wq
<이득우의 게임 수학:39가지 예제로 배운다! 메타버스를 구성하는 게임 수학의 모든 것> 구입 링크
https://link.coupang.com/a/9BqLd
유니티 에셋 스토어 링크
https://assetstore.unity.com?aid=1011lvz7h
(링크를 통해 도서/에셋 구입시 일정액의 수수료를 지급받습니다.)