농담곰담곰이의곰담농

[DirectX 11] 3D Transformations

by 브이담곰

📑 전공과목 교수님의 개별적인 튜토리얼 스크립트를 바탕으로 작성되었습니다.😊

The Geometry Pipeline

     3D->2D로 변환이 되는 과정에서는 수학적 절차가 존재한다.

 

1.  World Transformation : 생성되는 모든 오브젝트들이 정점에서 새로운 위치로 이동하는 것

Object는 정점(0,0,0)에서 생성된다.

    = 모든 게임 오브젝트들은 world의 중심에서 시작된다. 

 

2. View Transformation

   virtual camera를 생성하고 오브젝트들을 보이게 위치를 설정한다.

 

3. Projection Transformation

   생성된 오브젝트들을 virtual camera와의 거리에 따라 크기를 조절해준다.(=원근법 반영)

나의 귀여운 그ㅡ림

 

 


📌 World Transformation

 

1. Model Translation

2. Model Rotation

3. Model Scailing

 

📌 View Transformation

   축이 움직여도 그려져있던 도형 및 카메라는 이동하지 않는다. 축만 움직인다.

따라서 그리는 법  => 축을 이동 및 회전 하여 도형을 그린다.

📌 Projection Transformation


Tutorial Script

 

// global declarations

ID3D11Buffer* pVBuffer;                // the pointer to the vertex buffer
ID3D11Buffer* pCBuffer;                // the pointer to the constant buffer

튜토리얼의 변수 선언을 보면, 몇가지 다른점이 있는데. 

바로, constant buffer의 선언이 추가되었다는 것이다. 

 

✔  Vertex Buffer (Vertex = 정점)

    -  3D 공간상의 점을 이야기 함. x,y,z이외에 다른 정보도 갖는다.

    -  따라서 정점 버퍼란 기본적으로 정점정보를 갖고 있는 메모리 블록

    -  정점버퍼를 생성한 다음에는 반드시 Lock()과 Unlock()으로 포인터를 얻어내서 정점정보를 정점버퍼에 써넣어야 한다.

 

✔  Constant Buffer (Constant = 상수)

    - 장면의 물체마다 달라지는 상수 데이터를 담기 위한 저장공간. 


  

  우리가 정적인 오브젝트를 화면상에 표현할 때는 Vertex Buffer만 사용했고, 함수 또한 InitGraphic이라는 함수를 통하여 버텍스 객체를 생성하여 버퍼를 생성한 뒤 맵핑했었다.
  이제 움직임을 구현하기 위해서는 Constant 버퍼의 생성을 통해 World Transformation(transition, rotation, scailing)의 연산을 해줘야한다. 이에 대한 내용을 아래에서 다룰 것이다.

 오브젝트의 움직임은 "RenderFrame" 함수에서 이루어진다.

void RenderFrame(void)
{
    `````
    
    // switch the back buffer and the front buffer
    swapchain->Present(0, 0);
}

 

 

 

함수 내부에 있는 스크립트를 하나씩 설명하겠다.


D3DXMATRIX matRotate, matView, matProjection, matFinal; //1
D3DXMATRIX matScale; //2
D3DXMATRIX matTrans; //3

1.

matRotate: 회전 행렬

matView: 카메라 시점 행렬

matProjection: 투영 행렬( n차원-> n-1 차원으로 변환)

matFinal: 모든 연산(회전,이동,스케일링)을 마친 최종 행렬

 

2. matScale: 스케일링 행렬

 

3. matTrans: 이동 행렬


 

 static float Time = 0.0f; Time += 0.0001f;

전역 변수 Time, 매 함수 호출마다 값이 증가한다.


D3DXMatrixRotationX(&matRotate, Time);
D3DXMatrixRotationY(&matRotate, Time);
D3DXMatrixRotationZ(&matRotate, Time);

[회전 함수] : 회전행렬연산은 x,y,z 별로 나누어져있다. 


D3DXMatrixScaling(&matScale,3.0f, 0.25f,1.0f);

[스케일링 함수]


D3DXMatrixTranslation(&matTrans, 1.0f, 0.0f, 0.0f);

[이동 함수]


D3DXMatrixPerspectiveFovLH(&matProjection,
        (FLOAT)D3DXToRadian(45),                    // field of view 시야각
        (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
        1.0f,                                       // near view-plane  
        500.0f);

카메라 뷰잉 값을 정한다.

field of view(시야각): 시야각이 넓어지면 넓어질수록, 넓게 보이지만 물체는 작게보인다(like 물고기눈 by신진)


✅ Rotation

matFinal = matRotate * matView * matProjection;

* 행렬 곱의 순서는 매우 중요하다. 꼭 지킬 것!

 

X축 회전
Y축 회전
Z축 회전

✅ Translation

matFinal = matTrans * matView * matProjection;

X축으로 이동
Time 변수를 넣어서 x좌표 값을 증가시켰을 때

✅ Scailing

matFinal = matScale * matView * matProjection;

X,Y를 각각 3배씩 값을 늘렸을 때
Time 변수를 넣어 X,Y 스케일 값을 증가시켰을 때.

✅ Translation * Rotation * Scailing

matFinal = (matRotate * matTrans * matScale) *  matView * matProjection;
matFinal = (matRotate * matScale * matTrans) *  matView * matProjection;
matFinal = (matScale * matTrans * matRotate) *  matView * matProjection;
matFinal = (matScale * matRotate * matTrans) *  matView * matProjection;
matFinal = (matTrans * matRotate * matScale) *  matView * matProjection;
matFinal = (matTrans * matScale * matRotate) *  matView * matProjection;

행렬 연산은 연산 순서에 따라 결과가 매우 다르게 나온다. 3가지 연산의 순서를 바꿨을 떄 나올 수 있는 경우의 수 6가지를 지금부터 직접 보여주겠다. 결과가 각자 어떻게 달라지는지 예상해보고 실제 실행결과를 확인하자.


matFinal = (matRotate * matTrans * matScale) * matView * matProjection;
matFinal = (matRotate * matScale * matTrans) *  matView * matProjection;
matFinal = (matScale * matRotate * matTrans) *  matView * matProjection;

Scale과 Trans의 연산 순서는 바뀌어도 변화가 없다.

회전->x축이동->크기증가


D3DXMatrixTranslation(&matTrans, Time, 0.0f, 0.0f);

trans.x값을 시간마다 증가시킨 경우


matFinal = (matScale * matTrans * matRotate) *  matView * matProjection;
matFinal = (matTrans * matRotate * matScale) *  matView * matProjection;
matFinal = (matTrans * matScale * matRotate) *  matView * matProjection;

💡 실습결과 Scale의 연산순서는 상관이 없다. Trans와 Rotate의 순서가 중요한 것 같다.

D3DXMatrixTranslation(&matTrans, 1.0f, 0.0f, 0.0f);

일정 거리 이동 후 회전시에는 원점을 중심으로 공전한다.


D3DXMatrixTranslation(&matTrans, Time, 0.0f, 0.0f);

이동거리가 시간마다 증가할 경우 나선형으로 회전한다.


다음 포스트에서는 객체를 생성하여 여러가지 도형을 움직여보는 것을 포스팅 해보겠다.

'Client > directX' 카테고리의 다른 글

[DirectX11] Texture Normal(Bump) Mapping  (0) 2022.05.31
[DirectX11] DirectX 초기화 와 3D 그래픽의 이해  (0) 2022.04.21
[DirectX11] Render States  (0) 2021.12.19
[DirectX11] 2D 원 그리기  (0) 2021.11.10
[DirectX 11] 정점 버퍼  (0) 2021.10.06

블로그의 정보

농담곰담곰이의곰담농

브이담곰

활동하기