렌더링 파이프라인은 3D 세계에 대한 기하학적 표현과 이 세계를 바라보는 관점을 정의하는 가상 카메라를 이용해 2D 이미지를 만들어내는 역할을 담당한다.

왼쪽의 3D 세계에 배치된 물체와 카메라가 정면으로 보면 오른쪽 처럼 2D 이미지를 보여준다.



목표

- Direct3D에서 3D 물체를 표현하는 방법을 배운다.

- 가상 카메라를 모델링하는 방법을 배운다.

- 렌더링 파이프라인에 대해 이해한다. - 3D 장면의 기하학적 표현으로 2D 이미지를 만들어내는 과정을 배운다.



모델 표현

장면(scene)은 물체나 모델의 모음이다.

모델링 하는 물체의 기본 구성 성분이 다각형(Polygon)

다각형에서 두 개의 변이 만나는 지점을 버텍스(Verex) = 꼭지점이다.

세 개의 버텍스로 정의된 하나의 삼각형



버텍스 포맷

Direct3D 내의 버텍스는 공간적 위치 이외의 부가적인 특성으로 이루어져 있다.(예를들어, 하나의 버텍스는 법선 특성이외에도 색상 특성을 가질 수 있다.)

DIrect3D는 버텍스 포맷을 구성할 수 있는 유연성을 제공하는데, 다른 말로 하면 버텍스의 속성을 정의할 수 있도록 해준다.

커스텀 버텍스 포맷을 만들기 위해서는 먼저 선택한 버텍스 데이터를 포함할 구조체를 만드들어야 한다.


예제 코드



삼각형

삼각형은 3D 물체의 기본 구성 요소로서, 물체를 구성하기 위해서는 물체의 모양과 외형을 묘사하는 삼각형 리스트를 만들어야 한다.

삼각형 리스트는 우리가 그리고자 하는 각각의 삼각형에 대한 데이터를 포함한다.

예를 들어, 사각형을 만들기 위해서는 두 개의 삼각형으로 나누고 각각의 삼각형을 구성하는 버텍스를 지정해야 한다.


사각형은 두 개의 삼각형으로 만들어진다.

삼각형(v0, v1, v2)과 삼각형(v0, v2, v3) = 사각형

삼각형의 버텍스를 지정하는 순서는 매우 중요하며 이를 두르기 순서(winding order)라고 부른다.



인덱스

3D 물체를 구성하는 삼각형들은 동일한 버텍스들을 공유하는 경우가 많다.

사각형 예제에서는 단 두 개의 버텍스가 중복되었지만, 모델의 복잡성과 세밀함이 증가할수록 중복되는 버텍스의 수 역시 증가한다.


예제 입방체 그림

입방체는 8개의 독특한 버텍스를 가지고 있지만 이방체의 삼각형 리스트에는 상당수의 버텍스가 중복될 것이다.

이 문제를 해결하기 위해 우리는 인덱스의 개념을 이용한다.

버텍스 리스트와 인덱스 리스트를 구성한다.

버텍스 리스는 모든 독특한 버텍스들을 포함하며, 인덱스 리스트는 삼각형을 구성하기 위한 버텍스 리스트의 인덱스 값을 포함한다.


위에 사각형 그림의 버텍스 리스트

indexList 정의를 말로 바꾸어 설명한다면. 0,1,2를 이용해 삼각형0, 0,2,3을 이용해 삼각형1을 만든다.

WORD indexLis[6] = {vertexList[0], vertexList[1], vertexList[2], vertexList[0], vertexList[2], vertexList[3]};



가상 카메라

카메라는 관찰자가 볼수 있는 세계의 부분을 지정하는 것으로, 2D 이미지를 생성하기 위해 세계의 어떤 부분이 필요한지를 결정하며,

세계 내에 위치하며 보여질 공간의 부피를 정의한다.


그림 - 카메라가 볼 수 있는 공간의 부피를 정의하는 절두체


공간의 부피는 절두체(frustum)이며, 시야각과 가까운 평면, 먼 평면에 의해 정의된다.

사각 원뿔으 이용하는 이유는 모니터 스크린이 사각형인 것을 생각하면 쉽게 이해할 수 있을 것이다.

이 공간에 표함되지 않는 물체들은 보여지지 않으며 이후의 처리에서 제외되어야 한다. 이와 같은 데이터의 제외 처리를 클리핑(clipping)이라 부른다.



렌더링 파이프라인

3D 장면을 구성하고 가상 카메라를 설정한 뒤에는 모니터에 2D 표현을 만들어내는 과정을 수행해야 한다.

그림 - 요약된 렌더링 파이프라인


파이프 라인 내에서의 몇 가지 단계에 의해서 하나의 좌표 시스템에서 다른 시스템으로 기하물체를 변환하는 과정이 이루어진다.

이 변환에는 행렬이 이용되며, 변환 과정은 Direct3D의 책임 하에 이루어진다.



로컬 스페이스

모델링 스페이스라고도 불리는 로컬 스페이스는 우리가 물체의 삼각형 리스트를 정의하는 데 이용하는 좌표 시스템이다.

로컬 스페이스는 모델링 과정을 쉽고 단순하게 만들어주며, 자체의 로컬 좌표 시스템을 이용하는 것이 월드에서 직접 모델을 구성하는 것보다 훨씬 쉽다.

예를 들어, 로컬 스페이스를 이용하면 위치나 크기, 월드 내의 다른 물체와의 관계 등을 고려하지 않고도 모델을 구성할 수 있다.


그림 - 자체의 좌표 시스템을 이용해 정의된 차 주전자



월드 스페이스

자체의 로컬 좌표 시스템 내에 다수의 모델을 구성한 다음에는 이를 전역(월드) 좌표 시스템으로 옮겨 하나의 장면을 구성해야 한다.

로컬 스페이스의 물체들은 이동, 회전, 크기 변형 등을 포함하는 월드 변환이라는 작업을 거쳐 월드 스페이스로 옮겨진다.

월드 변환은 위치와 크기, 방위를 포함하는 각 물체 간의 관계를 정의함으로써 이루어진다.


그림 - 여러 개의 3D 물체들이 하나의 월드 좌표 시스템 내에서 서로 연결된다.



뷰 스페이스

월드 스페이스 내에서 기하물체와 카메라는 월드 좌표 시스템과 연계되어 정의된다.

한편, 카메라가 월드 내 임의의 위치나 방위를 가진다면 투영이나 그 밖의 작업이 어렵거나 덜 효율적이 된다.

따라서 작업의 수월함을 위해 카메라를 월드 시스템의 원점으로 변환하고, 카메라가 양의 z축을 내려다보도록 회전시켜야 한다.

이때 월드에 대한 관점이 바뀌지 않도록 하기 위해서는 카메라에 맞추어 월드 내의 모든 기하물체를 변환해야 하는데, 이와 같은 변환을 뷰스페이스 변환이라 하며, 이변환을 거친 뒤의 기하물체는 뷰스페이스 내에 위치한다고 말할 수 있다.



후면 추려내기

폴리곤은 두 개의 면을 가지고 있으며 하나의 면을 전면, 다른 면을 후면이라 부른다.

일반적으로 폴리곤의 후면은 절대 보여지지 않는데, 이는 장면 내의 물체들이 내부로 카메라를 넣는 것이 허용되지 않기 때문이다.

카메라는 절대로 폴리곤의 후면을 보지 못한다. 이와 같은 사실은 매우 중요하한데, 폴리곤의 후면을 볼 수 있느 ㄴ경우에는 후면 추려내기가 작동하지 않기 때문이다.


그림 - 전면 폴리곤과 후면 폴리곤을 가진 물체


그림에 카메라에 전면을 향하고 있는 폴리곤을 전면 폴리곤, 후면을 향하고 있는 폴리곤을 후면 폴리곤이라 한다.

전면을 향하고 있는 폴리곤들이 뒤쪽의 후면 폴리곤들을 가리고 있음을 알 수 있다.

Direct3D는 후면 폴리곤을 추려냄으로서(이후의 처리에서 제거) 상당한 이득을 추한다. 이와 같은 과정을 후면 추려내기(backface culling)라 한다.


그림 - 후면 폴리곤이 추려진 뒤의 장면


카메라의 입장에서 후면은 어차피 가려져 보이지 않으므로 동일한 이미지가 만들어진다.

이와 같은 처리를 위해서는 어떤 폴리곤이 전면 폴리곤이고 후면 폴리곤인지를 Direct3D의 입장에서 확인할 수 있어야 한다.

디폴트로 Direct3D는 두르기 순서의 시계 방향에(뷰 스페이스에서) 지정된 버텍스를 가진 폴리곤을 전면 폴리곤으로 취급하며,

두르기 순서의 시계 반대 방향에 지정된 버텍스를 가진 폴리곤을 후면 폴리곤으로 취급한다.


"뷰 스페이스"로 시점을 정의했다는 데 주의하자. 이것은 삼각형이 180도 회전할 경우 두르기 순서가 뒤집히기 때문이다. 즉, 로컬 스페이스에서 시계 방향의 두르기 순서를 가지고 있던 삼각형이라도 뷰 스페이스로 변환하면 회전에 의해 시계 방향의 두르기 순서가 아니게 될 수 있다.


만약 표준적인 추려내기 동작이 마음에 들지 않는다면 D3DRS_CULLMODE 렌더 상태를 수정하여 동작을 변경하는 것도 가능하다.

Device->SetRenderState(D3DRS_CULLMODE, Value);

Value에는 세가지 중 하나를 선택적으로 사용할 수 있다.

D3DCULL_NONE - 후면 추려니기를 완전히 끈다.

D3DCULL_CW - 시계 방향 두르기를 가진 삼각형을 추려낸다.

D3DCULL_CCW - 시계 반대 방향 두르기를 가진 삼각형을 추려낸다. 디폴트 상태이다.



조명

광원은 월드 스페이스 내에 정의되지만 뷰 슾이스 변환에 의해 뷰 스페이스로 변환된다.

광원은 물체에 명암을 추가하여 장면에 사실감을 더해준다.



클리핑

시야 볼륨 외부의 기하물체를 추려내야 한다. 이 과정을 클리핑이라 한다.

시야 철두체에서의 삼각형 위치는 다음과 같이 세 가지로 분류할 수 있다.

  • 완전한 내부 - 삼각형이 완전히 절두체 내부에 위치하면 그대로 보존되어 다음 단계로 진행한다.
  • 완전한 외부 - 삼각형이 완전히 절두체 외부에 위치하면 추려내어진다.
  • 부분적 내부(부분적 외부) - 삼각형이 부분적으로 절두체 내부에 위치하면 삼각형을 두 개의 부분으로 분리힌다. 절두체 내부의 부분은 보존되며, 나머지는 추려내어진다.

그림 - 시야 볼륨 외부의 기하물체를 추려낸다.



투영

뷰 스페이스에서는 3D 장면의 2D 표현을 얻는 과정이 남아있다. 이와 같이 n 차원에서 n-1 차원을 얻는 과정을 투영(projection)이라 한다.

투영은 여러가지 방법이 있지만 원근 투영(perspective projection)이라는 방법으로, 원근법을 이용하여 기하물체를 투사한다.

즉, 카메라에서 멀리 떨어진 물체는 가까운 물체에 비해 작게 나타난다. 이와 같은 타입의 투영은 3D 장면을 2D 이미지로 표현하는 데 가장 적합하다.

그림 - 투영 윈도우의 3D 포인트 투영


투영 변환은 우리의 시야 볼륨(절두체)을 정의하고, 절두체 내의 기하물체를 투영 윈도우에 투영하는 과정을 담당한다.

D3DX 함수를 이용하여 절두체 선언에 따른 투영 행렬을 만들어내는 방법만 알아두자.



절두체의 속성들

종횡비 인자를 계산하기 위해서는 약간의 작업이 필요하다. 투영 윈도우의 기하물체들은 결국 스크린 스페이스로 변환되는데, 정사각형(투영 윈도우)에서 직사각형인 스크린으로의 변환에는 왜곡이 따르게 된다.

종횡비는 간단히 말해 화면 너비와 높이의 비율이며, 정사각형에서 직사각형으로의 매핑에 의해 발생하는 왜곡을 보정하는 역할을 한다.


종횡비 = 화면 너비 / 화면 높이


투영 행렬을 얻기 위해서는 D3DTS_PROJECTIon에 변환 타입을 전달하고 IDirect3DDevice9::SetTransform 메서드를 호출하면 된다.

코드는 90도의 시야 각과 거리 1의 가까운 평면, 거리 1000의 먼 평면을 가지는 절두체에 맞는 투영 행렬을 만들어낸다.



뷰포트 변환

뷰포트 변환은 프로젝트 윈도우의 좌표를 뷰포트라 불리는 화면의 직사각형으로 변환하는 과정을 말한다.

게임에서의 뷰포트는 보통 직사각형의 전체 화면이 되지만, 윈도우 모드에서 실행하는 경우에는 클라이언트 영역이나 화면의 일부가 될 수도 있다.

뷰포트 사각형은 이를 포함하고 있는 윈도우와 상대적이며, 윈도우 좌표를 이용해 지정된다.


그림 - 뷰포트 사각형


Direct3D에서는 D3DVIEWPORT9 구조체를 이용해 뷰포트를 표현하며, 이 구조체는 다음과 같이 정의된다.

앞 부분의 네 데이터 멤버는 뷰포트를 포함하는 윈도우와의 상대적인 뷰포트 사각형을 정의한다.

MinZ 맴버는 최소 깊이 버퍼 값을 지정하며, MaxZ는 최대 깊이 버퍼 값을 정의한다.

Direct3D는 0부터 1까지의 깊이 버퍼를 이용하므로, 특수한 효과를 원하는 것이 아니라면 MinZ와 MaxZ에도 이에 맞는 값을 지정해야 한다.


Direct3D는 자동으로 뷰포트 변환을 수행해주지만 뷰포트 변환을 수행하는 행렬이 어떻게 구성되었는지를 확인해보는 것도 나쁘지는 않을 것이다.

식의 변수들은 3DDVIEWPORT9 구조체에서 설명한 것과 동일하다.



래스터라이즈

스크린 좌표로 버텍스들을 변환한 다음에는 2D 삼각형들의 리스트를 가지게 된다.

래스터라이즈 단계는 각각의 삼각형을 그리는 데 필요한 픽셀 컬러들을 계산하는 과정이다.


그림 - 래스터라이즈를 거친 스크린 삼각형


래스터라이즈 과정은 엄청난 작업 양을 필요로 하므로 반드시 전용 그래픽 하드웨어에서 처리되야 한다.

래스터라이즈의 결과물은 모니터에 바로 디스플레이 할수 있는 2D 이미지가 된다.



요약

  • 3D 물체들은 물체의 모양과 외각을 묘사하는 삼각형들의 리스트인 삼각형 메쉬들로 표현된다.
  • 가상 카메라는 절두체로 모델링되며 절두체 내의 공간이 카메라가 "보는" 것이 된다.
  • 3D 물체들은 로컬 스페이스 내에 정의되며 모두 하나의 월드 스페이스 시스템으로 옮겨진다. 투영을 위해 서는 추려내기와 같은 다른 작업이 필요하며, 이어 뷰 스페이스로 물체를 변환하고, 카메라를 원점으로 옮기고 양의 z축을 내려다보도록 하는 과정이 진행된다. 뷰 스페이스 내에 놓여진 물체들은 투영 윈도우로 투영되며, 뷰 포트 변환을 통해 투영 윈도우의 기하물체가 뷰포트로 변환된다. 이제 최종적으로 래스터라이즈를 거쳐 최종 2D 이미지를 구성하는 각각의 픽셀 컬러가 계산된다.


반응형