-
[25] - DirectXMathGraphics 2021. 7. 31. 01:09
hw3d/hw3d at T19-End · planetchili/hw3d (github.com)
(26) C++ 3D DirectX Tutorial [Introduction] 0 - YouTube
큰 도움이 되는 강의입니다.
D3D에는 여러 수학 기법들을 제공합니다. 보통 D3D Library에 포함이 되어 있습니다. [24]에서 행렬을 손으로 다 기입했던 것처럼 해도 큰 상관은 없습니다. 그런데 귀찮습니다. 행렬 간의 연산, 행렬과 벡터의 연산 등을 일일이 구현하기도 귀찮습니다. 그래서 선택할 수 있는 것이 DirectXMath입니다. 추가적으로 DirectXMath는 SIMD[Single Instruction Multiple Data] Optimization을 제공합니다. 가령, Row vector [1,2,3,4] 와 [5,6,7,8]의 합을 구할 때 네 번의 덧셈을 하지 않고 한 번의 덧셈으로 네 번의 덧셈을 처리할 수 있다는 뜻입니다. 조금 Rough하게 말하면 네 배의 속도를 낼 수 있겠습니다. 물론 꼭 장점만이 존재하는 건 아닙니다. 이런 SIMD의 기능은 종종 Alignment의 Issue를 불러오기 때문입니다. DirectXMath가 케어를 해주기는 하지만 전부 해주진 못할 겁니다.
모든 실험이 현재 Graphics에서 이루어지고 있습니다. 따라서 Graphics class 정의된 파일에서 해당 헤더파일을 불러옵니다. 그런데 키보드로 쳐보면 DirectX는 조금 치기 번거롭습니다. 따라서 매번 함수를 호출할 때마다 DirectX::를 불러오는 대신에 namespace를 사용해서 편하게 쓰도록 합니다.
별 것 아니지만 생산성이 향상됩니다 가장 먼저 대체할 수 있는 것은 당연히 행렬입니다. 육각형을 회전 시키기 위해서 선언했던 행렬을 dx로 대체합니다. 기본적으로 XMMATRIX는 floating point의 4x4 행렬입니다. 주의할 점이 있습니다. 이렇게 선언된 XMMATRIX라든가 DirectXMath의 각종 인스턴스는 직접 접근하지 말고 Interface를 통해서 접근하는 편이 좋습니다. 일종의 Black Box인데 나름의 방식으로 SIMD 최적화를 시키기 위해 데이터들을 Load했기 때문입니다.
기존의 코드를 위와 같이 바꾸었습니다. 작성하기도 편하고 보기도 좋고 똑같이 잘 돌아갑니다. XMMATRIX는 Asterisk 연산자가 Overload되어 있습니다. 따라서 다음과 같은 코드도 위와 완전히 같은 역할을 합니다.
[24]에서 Vertex Shader는 행렬을 Column major로 처리하지만 row_major를 앞에 주어서 row major로 처리할 수 있게 만들었습니다. 그러나 약간의 성능 저하가 우려된다는 말을 했습니다. row-column의 변환은 Transpose로 간단하게 처리할 수 있습니다.
이번에는 약간의 다른 실험을 해보도록 합니다. 이 물체가 마우스를 따라 올 수 있도록 구현합니다. 그러려면 가급적 Mesh가 작은 편이 좋을 것 같습니다. 강의 전에 홀로 생각해보면, 이 Test 함수의 Parameter로 마우스의 x,y의 값을 갖고 와서 Translation 해주면 끝일 것 같습니다. 근데 해보면 이상한 결과를 얻습니다.
현재 작업(Rendering)을 하고 있는 공간은 NDC입니다. 하지만 마우스 포인터의 위치는 NDC가 아닙니다. 그래서 어떤 값이든 크기가 1보다 큰 값이라면 화면에 출력 자체가 안 되는 겁니다. 그럼 Window 크기에 맞게 Scailing해봅니다. Hard coding으로 다음과 같이 작성해봅니다.
상태가 여전히 좋지 않습니다. 특히 수직으론 아예 반대로 움직입니다. NDC는 -1부터 1까지의 범위입니다. 그런데 단순히 800과 600으로 나누어주면 0부터 1까지의 영역을 가리키게 됩니다. 따라서 각 값을 400과 300에 -1을 해주면 -1부터 1까지의 범위로 만들 수 있습니다. 하지만 여전히 수직움직임이 반대로 동작하는 것은 막을 수 없을 것입니다.
그런데 뭔가 직관적으로 y값을 negate해주면 될 것 같습니다. 해보면 됩니다. 마우스를 잘 따라옵니다. 이유는 Mouse, Pixel, Graphics의 좌표에선 y의 양의 방향이 아래입니다. 반대로 NDC에서는 y의 양의 방향이 위쪽이기 때문입니다. y값 전체를 Negate해주면 문제가 해결됩니다.
결과 DirectXMath는 유용한 기능들을 아주 많이 갖고 있습니다. DirectXMath programming guide - Win32 apps | Microsoft Docs
DirectXMath programming guide - Win32 apps
DirectXMath provides a math solution optimized for Windows.
docs.microsoft.com
'Graphics' 카테고리의 다른 글
[27] - Bindable/Drawable System (0) 2021.08.01 [26] - Z-buffer (0) 2021.07.31 [24] - Constant Buffer (0) 2021.07.30 [23] - Pipeline experiments (0) 2021.07.30 [22] - Viewport and clip space (0) 2021.07.23