3D Graphics

3D Graphics Rendering Pipline

hunhun4949 2024. 8. 19. 21:50

렌더링 파이프라인은 3D 그래픽을 2D 화면에 표시하기 위한 일련의 연산과정이다.

 

DirectX11기준 다음과 같은 주요 렌더링 파이프라인 단계를 갖는다.

  1. 입력 어셈블러(Input Assembler)
  2. 정점 셰이더(Vertex Shader)
  3. 헐 셰이더(Hull Shader) optional
  4. 테셀레이터(Tessellator) optional
  5. 도메인 셰이더(Domain Shader) optional
  6. 기하 셰이더(Geometry Shader) optional
  7. 스트림 출력(Stream Output) optional
  8. 래스터라이저(Rasterizer)
  9. 픽셀 셰이더(Pixel Shader)
  10. 출력 병합기(Output Merger)

위 단계들 중 optional이 붙은것은 DirectX가 버전업이 되면서 추가가 된 파이프라인 단계들이다.

오늘은 일단 필수 파이프라인 단계인 IA, VS, RS, PS, OM 이 다섯개에 대해서만 알아보자.

 

IA(Input Assembler)

IA는 렌더링 파이프라인의 첫 단계로, 3D 모델의 기본 데이터를 준비하는 단계다.

IA는 다음과 같은 작업을 수행한다.

  1. 버텍스 버퍼와 인덱스 버퍼에서 데이터를 읽어온다. 버텍스 버퍼는 3D 모델의 각 정점(버텍스)에 대한 정보(위치, 색상, UV, 등)를 포함하고, 인덱스 버퍼는 이 점들을 어떤 순서로 연갈하여 삼각혐을 만들지 지정한다.
  2. PrimitiveTopology를 적용합니다. 이는 점들을 어떻게 연결하여 기본 도형(삼각형, 선, 점 등)을 만들지 결정합니다. PrimitiveTopology의 타입은 아래 사진처럼 여러개가 있다. 보통은 삼각형 기준으로 값을 저장하는 TRIANGLELIST를 사용한다.
  3. 인스턴싱을 지원한다. 인스턴싱은 동일한 모델을 여러 번 그릴 떄 각각 따로따로 그리는 대신, 각 인스턴스마다 약간씩 다른 속성(위치, 크기, 색상, 등)을 받아온뒤 한꺼번에 Draw 콜 처리를 해준다. 이를 사용하는 이유는 Draw콜 한번당 IA->OM까지 작업을 수행하는데 이게 상당한 연산량을 요구하는데, 인스턴싱을 사용하면 Draw콜의 빈도수를 상당히 줄일수 있다.
  4. 필요한 경우 버텍스 캐시 최적화를 수행한다. 이는 최근에 사용된 버텍스 데이터를 재사용해서 성능을 향상시키는 방법이다.

 

VS(Vertex Shader)

VS는 3D모델의 각 버텍스에 대해 실행되는 단계이다.

  1. 버텍스 변환 : 모델 공간의 버텍스 위치를 월드 공간, 뷰 공간, 그리고 클립 공간으로 변환해준다. 이는 world, view, projection 행렬을 사용해서 수행한다. 줄여서 wvp 변환이라고도 한다.
    WVP변환 + Viewport변환
  2. 버텍스 속성 계산 : 조명, 텍스처 좌표(texCoord), 색상 등의 버텍스 속성을 계산하거나 변형한다. 예를 들어 노말 맵핑을 위해 탄젠트와 바이노말을 계산할 수 있다.
  3. 스키닝 : 애니메이션 모델의 경우, 버텍스의 위치와 노말을 본 변환에 따라 조정한다.
  4. 모핑 : 두 개 이상의 모델 형태 사이를 부드럽게 전환하는 효과를 구현할 수 있다.
  5. 절차적 변형 : 바람에 날리는 잔디나 물결치는 물 표면 등의 효과를 위해 버텍스 위치를 동적으로 조정할 수 있다.

 

RS(Rasterizer)

RS는 3D 공각의 기하학적 데이터를 2D 화면의 픽셀로 변환하는 단계이다.

  1. 클리핑 : 카메라 앵글 밖의 프리미티브를 제거하거나 잘라낸다. 다른말로 FrustumCulling이라고도 한다. 이는 환면에 보이지 않는 부분을 렌더링 하지 않음으로써 성능을 향상시켜주는 방법이다.
  2. 뷰포트 변환 : 클립 공간의 좌표를 화면 공간의 좌표로 변환한다. 위에 사진을 참고하자.
  3. 삼각형 설정 : 버텍스로 정의된 삼각형을 픽셀로 변환할 준비를 한다. 이 과정에서 삼각형의 방향(전면, 후면)을 결정하고, 필요에 따라 back-face culling(후면은 렌더링 하지 않는것)을 수행한다. 삼각형의 정면 후면은 정점들이 찍힌 순서로 결정된다. 정면의 기준은 왼손 좌표계냐 오른손 좌표계냐에 따라 다르다. 왼손 좌표계인 DirectX11기준 정점들이 시계방향으로 찍혀있으면 정면이고 반시계방향으로 찍혀있으면 후면이다. 
  4. 스캔 변환 : 삼각형을 구성하는 픽셀을 결정한다. 이 과정에서 각 픽셀에 대한 깊이 값과 보간된 버텍스 속성(색상, 텍스처 좌표 등)을 계산한다. 예를 들면 색이 RGB(128, 128, 0)인 정점과 RGB(0, 64, 0)인 정점 중간에 위치한 픽셀은 첫번째 정점 색상 * 0.5 + 두번째 정점 색상 * 0.5의 색상값, RGB(64, 96, 0)을 가지게 된다. 
  5. 멀티샘플링 안티앨리어싱(MSAA) : 활성화된 경우, 각 픽셀을 여러 개의 샘플로 나누어 처리해서 가장자리의 계단 현상을 줄인다. 

PS(Pixel Shader)

PS는 각 픽셀의 최종 색상을 결정하는 단계이다.

  1. 텍스처 샘플링 : 텍스처 맵에서 색상 정보를 가져와 적용한다. 여러 텍스처를 조합하거나 특수한 샘플링 기법(밉맵핑, 애니소트로픽 필터링 등)을 사용 할 수 있다. 오브젝트에 스킨을 씌워주는 과정이라 생각하면 된다.
  2. 조명 계산 : 다양한 조명 모델(Phong, Blinn-Phong, PBR 등)을 사용해서 픽셀의 발기와 색상을 계산한다. 이는 Diffuse, Specular, Ambient 등의 요소를 고려해야한다.
  3. 노말 맵핑 : 오브젝트 표면의 미세한 굴곡을 일일히 모델링하면 엄청난 시간과 노력, 그리고 연산량을 잡아먹을거다. 그래서 특정 위치의 굴곡값을 일일히 모델링해서 표현하는 대신 텍스처에 색상정보로 저장을 해서 그 값에 따라 빛 연산처리를 해준다. 쉽게 눈속임이라 생각하면 된다.  
  4. 그림자 계산 : 섀도우 맵이나 다른 기법을 사용해서 그림자를 적용한다.
  5. 특수 효과 : 반사, 굴절, 서브서피스 스캐터링, 대기 효과 등 다양한 특수 효과를 구현할 수 있다.
  6. 후처리 효과 : 블룸, 모션 블루, 피사계 심도 등의 효과를 위한 중간 데이터를 생성할 수 있다.

OM(Output Merger)

OM은 렌더링 파이프라인 최종 단계로, 여러 버퍼이 정보를 결합해서 최종 픽셀 색상을 결정하는 단계다.

  1. 깊이 테스트 : 각 픽셀의 깊이 값을 깊이 버퍼와 비교해서 가시성을 결정한다. 이를 통해 앞쪽 물체가 뒤쪽 물체를 가리는 것을 구현한다.
  2. 스텔실 테스트 : 스텐실 버퍼를 사용하여 픽셀의 렌더링 여부를 결정한다. 이는 그림자 볼륨, 포탈, 거울 등의 효과에 사용된다.
  3. 알파 블렌딩 : 반투명한 객체를 처리할 떄 사용된다. 현재 픽셀의 색상과 이미 렌더링된 색상을 알파 값에 따라 혼합한다.
  4. 색상 마스킹 : 특정 색상 채널의 쓰기를 제어할 수 있다.
  5. 논리 연산 : 픽셀 색상에 대해 비트 단위의 논리 연산을 수행할 수 있다.
  6. 멀티 렌더 타겟(MRT) 여러 개의 렌더 타겟에 동시에 출력할 수 있다. 이는 디퍼드 렌더링 등의 고급 기법에 사용된다.