이론/그래픽스

렌더링 파이프라인

tsyang 2021. 10. 26. 01:10

GPU

  • 원래 렌더링은 CPU로만 처리하고 있었는데 GPU가 추가되면서 이를 이용한 하드웨어 가속이 가능해졌다. 동시에 렌더링 파이프라인이라는 개념이 쓰이게 됐고 이는 여러 Graphics API의 기반이 된다.
  • CPU가 GPU에 명령을 보내어 각각 자신의 일을 병렬적으로 처리한다. 
  • GPU에는 VRAM이라는 전용 메모리가 존재하는데, 여기에는 텍스쳐나 메시 데이터 혹은 이중 버퍼링등에 쓰이는 버퍼가 저장된다. 기기별로 하나의 물리적인 RAM을 CPU+GPU가 나눠서 쓰기도 한다.

렌더링 파이프라인

  • 래스터(raster) : 화상 정보를 표현하기 위해 이미지를 2차원 배열 형태의 픽셀로 구성하여 표현하는 것. 즉, 연속된 픽셀들의 집합.
  • 렌더링 파이프라인 : 3차원 이미지를 2차원 래스터 이미지로 표현하기 위한 단계적인 방법.

 

오브젝트를 렌더링 하기 위해서는 많은 데이터가 필요하다.

  1. 오브젝트의 입체적 형태를 나타내는 메시 정보
  2. 텍스쳐 정보 (알베도, 노말, 스페큘러...)
  3. Lighting 처리에 관련된 쉐이더
  4. Transform
  5. 기타

그리고 이런 정보들을 이용하여 오브젝트가 렌더링 되는 과정을 렌더링 파이프라인 이라고 한다.

 

렌더링 파이프라인은 크게 3가지로 나눌 수 있다.

  1. 애플리케이션
  2. 지오메트리
  3. 래스터라이저

 

 


 

애플리케이션 스테이지

애플리케이션 상에서 처리되는 단계를 말한다. 이 단계는 보통 CPU에서 처리하는 단계이기 때문에 엄밀히 따지면 렌더링 파이프라인이라고 하기 좀 그렇다. 이 단계에서는 컬링을 사용하여 렌더링 될 오브젝트를 선별한다. 또 배칭도 이 단계 중 하나라고 볼 수 있다.

 


 

 

지오메트리 스테이지

여기서는 버텍스와 폴리곤을 처리한다. 

 

버텍스 트랜스폼

VRAM에 저장된 버텍스 데이터는 단순히 메시 형태만 반영되어 있는 데이터이다. 모든 버텍스와 노멀을 월드 좌표계로 옮겨주는 월드 트랜스폼, 다시 이것을 카메라 스페이스로 이동시켜주는 뷰 트랜스폼, 그리고 이것을 2D 상의 위치로 매칭시켜주는 프로젝션이 있다.

 

버텍스 쉐이더

트랜스폼 변환들은 여기서 일어난다. 즉, 버텍스들을 처리하는 쉐이더이다. 버텍스 쉐이더는 버텍스의 위치 변환이나 노멀 및 컬러도 결정한다. 

 

지오메트리 생성 

  • 버텍스 쉐이더가 트랜스폼을 결정하고 나면 버텍스들을 연결하여 도형을 만든다. 이때 생성된 메시 도형을 지오메트리라 부른다. 최근에는 쉐이더로 지오메트리 생성에 관여해 테셀레이션을 수행할 수 있다.
  • 중요한 것은 파이프 라인에 입력된 버텍스들은 모두 지오메트리화 된다는 것이다. 따라서 카메라 밖에 있어서 렌더링 되지 않는 버텍스들도 지오메트리화 되기에 카메라 영역 밖에 있는 오브젝트들이 렌더링 파이프라인을 거치지 않도록 하는 컬링이 필요하다. 
  • 메시의 폴리곤 수가 성능에 큰 영향을 미친다.

 


 

래스터라이저 스테이지

메시의 폴리곤을 픽셀로 매칭시키는 과정을 래스터라이제이션(Rasterization) 이라고 한다. 래스터라이제이션이 끝나면 최종적으로 각각 픽셀의 최종 색이 결정된다.

 

뎁스 버퍼(Z 버퍼)

프래그먼트(픽셀) 쉐이더에서 결정된 픽셀은 RGBA외에도 픽셀과 카메라의 거리를 별도로 저장하며 이때 저장되는 버퍼를 뎁스 버퍼라고 한다. 뎁스 버퍼를 통해 픽셀을 렌더링 할 때 깊이 판정(뎁스 테스트)를 수행한다.

현대에는 프래그먼트(픽셀) 쉐이더로 넘어가기 전에 뎁스 테스트를 수행해 필요없는 정보를 걸러낸다. 

 

프레그먼트(픽셀) 쉐이더 : 프래그먼트 쉐이더는 픽셀 쉐이더라고 불리지만 엄밀히 말하면 프래그먼트는 최종 픽셀이 되기 전의 데이터들을 의미한다. 그러나 결론적으로 픽셀이 되므로 동일하게 봐도 무방하다. 이 단계에서는 픽셀들의 최종 렌더링 색을 결정한다. 

 


렌더 루프

더블 버퍼링

렌더링을 하는 동안 한 프레임에 일어나는 일들은 대충 다음과 같다.

 

  1. 프레임이 시작되고 로직을 처리한다.
  2. 컬링 연산을 수행해 불필요한 렌더링 부하를 방지한다. (유니티는 기본적으로 프러스텀 컬링 수행)
  3. 백 버퍼에 씬을 렌더링한다. 각 오브젝트마다 드로우콜이 발생하며 버텍스쉐이더와 프래그먼트 쉐이더와 같은 GPU 파이프라인을 거친다. 
  4. 포스트 프로세싱을 수행한다. 포스트프로세싱 역시 버퍼에 렌더링을 하는 것이므로 한 번 이상의 드로우 콜이 발생한다.
  5. 백 버퍼와 프론트 버퍼를 스왑한다.

'이론 > 그래픽스' 카테고리의 다른 글

컬링(Culling)  (0) 2021.12.14
배칭(Batching)  (2) 2021.11.15
드로우콜(Draw Call)  (3) 2021.11.13
병목(Bottleneck)  (0) 2021.11.03
곡선(Curve) & 스플라인(Spline)  (2) 2021.07.11