
02. 렌더링 파이프라인(Rendering Pipeline)
1) GPU의 의미
폰 노이만 구조
- 폰 노이만 구조란 CPU, 메모리, 프로그램 구조를 갖는 컴퓨터 구조로 지금까지 컴퓨터는 대부분 이러한 구조를 가진다
GPU
- GPU는 이러한 폰 노이만 구조를 기반으로 하는 CPU를 보조하기 위한 시스템이다
- 그래픽 카드와 GPU가 도입되면서 하드웨어에서 3D 렌더링 가속을 할 수 있게 되었다
2) 게임 루프(Game Loop)
게임 루프
- 초기화 -> 데이터 업데이트 -> 렌더링 -> 해제 과정이다

- 이 과정에서 포인트는 데이터 업데이트과정이 처리된 이후에 렌더링이 이루어지고 이 과정이 반복된다는 점인데 이 과정은 유니티 게임 오브젝트의 스크립트 라이프 사이클과 크게 다르지않다
- 초기화 -> 데이터 업데이트 [물리 업데이트 -> 인풋 데이터 처리 -> 게임 로직 처리] -> 렌더 [씬 렌더링 -> GUI 렌더링] -> 해제

3) 렌더링 루프(Rendering Loop)
렌더링 루프
- 렌더링 과정을 살펴보면 모든 오브젝트를 한번에 그리는 것이 아닌 오브젝트를 순차적으로 그리고 모든 오브젝트가 렌더링 되면 화면에 출력된다
4) 렌더링 파이프라인(Rendering Pipeline)
렌더링 데이터
- 입체적 형태를 나타내는 메시 정보
- 알베도, 노멀, 스페큘러 등의 텍스처 정보
- 라이팅을 어떻게 처리할지 결정하는 쉐이더 정보
- 위치, 회전, 스케일을 정의하는 트랜스폼 정보
- 기타 등등
렌더링 파이프라인
- 3D 데이터를 2D 이미지 상으로 그리는 과정 과정
- 렌더링 파이프라인을 잘 이해하고 있어야 하는 이유
만약 렌더링 성능이 떨어졌다면 파이프라인 어느 구간에서 막혔는지 파악하고 해결하기 위해서는 렌더링 파이프라인을 잘 이해하고 있어야 한다
렌더링 성능이 떨어졌을 때 짜잔 하고 해결하는 나를 상상해 보며...
- 렌더링 파이프 라인을 아주 큰 단위로 보면 다음과 같다

1. 애플리케이션 스테이지 (Application Stage)
- 애플리케이션 스테이지는 말 그대로 애플리케이션 상에서 처리되는 단계로 보통 CPU에서 연산되는 단계이다
- 현재 프레임에서 렌더링 가능한 오브젝트들이 컬링 연산에 의해 선별하는 연산과 배칭처리를 위한 연산도 GPU파이프라인에 진입하기 전 단계인 애플리케이션 스테이지 단계에서 처리된다
2. 지오메트리 스테이지 (Geometry Stage)
- 지오메트리 스테이지는 지오메트리를 구성하는 요소인 버텍스와 폴리곤의 처리를 담당한다
전반적으로 오브젝트의 버텍스를 화면상 적절한 위치에 배치시키는 과정이다
메시
- 컴퓨터에 그림을 그리기 위해서는 최소 단위인 점이 필요하고 점 두개가 이어져서 선, 선 세개가 이어져서 면이되고 면들이 모여서 오브젝트의 형태를 보여주는 메시가 된다
메시는 리오넬 메시... 죄송합니다
컴퓨터 그래픽스에서 삼각형을 만들기 위한 최소단위인 점을 버텍스라고 하고 삼각형을 폴리곤이라고 부른다
사각형은 삼각형폴리곤 두개를 합쳐서 만든다
GPU에 저장되어 있는 버텍스 데이터들을 가져와서 적절한 위치에 그려주기 위해서 하는 위치면환 트랜스폼
- 저장되어있는 버텍스 데이터는 원점 기준의 메시 모델에 대한 위치 데이터만 갖고 있고 이를 로컬스페이스라고 표현한다
메시 인스턴스를 로컬 좌표계에서 월드 좌표계로 변환 시켜주는 과정
로컬 좌표계를 뚫고 세상 밖으로 나온 오브젝트
월드 좌표계에 있는 오브젝트는 카메라를 통해 디스플레이 되는데 이를 위해 오브젝트의 버텍스들을 카메라에 상대적인 위치로 변환해주는 과정
- 3D 공간을 2D 상의 위치로 매칭시켜주는 과정을 프로젝션 (투영, projection)이라고 하고
원근법을 적용하는 퍼스펙티브 프로젝션 (원근 투영, perspective projection)
원근법이 제거된 오쏘그래픽 프로젝션 (직교 투영, orthographic projection)이 있다
버텍스 쉐이더 (Vertecx Shader)
- 트랜스폼 변환은 버텍스 쉐이더에서 이루어진다
- 월드-뷰-프로젝션 트랜스폼 (World-View-Projection transform) : 앞서 설명한 월드 트랜스폼, 뷰 트랜스폼, 프로젝션 트랜스폼을 합쳐서 부르는 말
- 버텍스 쉐이더에서 메시의 버테스가 적절한 위치에 놓일 수 있게 행렬을 곱해 변환을 적용하고
노멀 및 컬러도 버텍스 쉐이더에서 결정된다
만일 픽셀별로 처리되는 라이팅이 아니라 버텍스 별로 처리되는 라이팅이라면 버텍스 쉐이더에서 처리된다
지오메트리 생성
- 지오메트리 (Geometry) : 버텍스 쉐이더를 거치고 만들어진 버텍스들이 연결되어 선이 만들어지고 도형의 형태가 될 때 이 도형을 지오메트리라고 부른다
- 지오메트리 생성은 버텍스 쉐이더에서 버텍스의 트랜스폼들이 결정되고 나면 다음 단계에서 자동으로 이루어진다
- 일부 최신 그래픽스 API는 쉐이더로 지오메트리 생성 단계에 관여해서 지오메트리 쉐이더(Geometry Shader), 헐 쉐이더(Hull Shader), 도메인 쉐이더(Domain Shader) 등을 통한 테셀레이션(Tessellation)을 수행할 수 있다
- 테셀레이션(Tessellation) : 테셀레이션은 입력받은 버텍스 외에 추가로 버텍스를 생성하여 도형의 밀도 및 복잡도를 늘려 디테일을 더해주는 기법이다
- 여기서 중요한 점은 파이프라인에 입력받은 버텍스들은 모두 지오메트리화 된다는 점으로 만일 카메라 기준 밖에 렌더링 되지 않는 버텍스들이 존재한다고 해도 모두 버텍스 쉐이더를 거쳐 지오메트리화 된다 이렇게 되면 버텍스가 많아져 지오메트리 스테이지에서 병목이 발생할 확률이 높다
그렇기에 카메라 밖의 오브젝트는 렌더링 파이프라인을 저치지 않도록 해주는 컬링(Culling) 기법이 중요하다
3. 래스터라이저 스테이지 (Rasterizer Stage)
- 래스터라이저 스테이지는 오브젝트를 그리는 픽셀들을 추리고 그 픽셀의 색을 결정하는 과정으로 메시의 폴리곤에 속한 영역을 픽셀로 매칭시키는 과정이다
뎁스 버퍼(Depth Buffer), Z 버퍼(Z Buffer)
- 프래그먼트(혹은 픽셀) 쉐이더에서 결정된 생상 정보는 컬러 버퍼에 저장되는데 이 컬러 버퍼 이외에 픽셀 깊이값을 별도의 버퍼로 저장하는데 이를 Z 버퍼 또는 뎁스(Depth) 버퍼라고 부른다
- Z 버퍼는 카메라로부터 떨어진 거리값을 저장하는데 일반적인 상황에 피셀이 Z 버퍼에 저장된 픽셀보다 앞에 있어야 렌더링이 된다
- 깊이 판정은 Z버퍼에 저장되어 있는 픽셀의 깊이값과 출력하고자 하는 픽셀의 깊이값을 비교하는데 이를 Z테스트 혹은 뎁스(Depth, 깊이) 테스트라고 부른다
Z버퍼는 컬러 버퍼와 동일한 해상도를 가진다
프래그먼트 쉐이더 (Pragment Shader)
- 프래그먼트 쉐이더는 픽셀들의 최종 렌더링 색을 계산한다
이 단계에서 텍스처로부터 생상을 읽어와 적용하고, 그림자도 적용하는 등의 다양한 일을 처리한다
블렌딩 (Blending)
- 투명도를 가진 오브젝트는 픽셀을 렌더링할 때 알파 블렌딩 (Alpha Blending) 과정을 거친다
5) 정리
더블 버퍼링 (Dubble Buffering)
- 두 개의 버퍼를 사용해서 1번 버퍼가 화면에 나타나는 동안 2번 버퍼에 프레임을 렌더링 하고 2번 버퍼가 화면에 나타나는 동안 1번 버퍼에 프레임을 렌더링 한다

화면에 보이는 버퍼를 프론트 버퍼 렌더링 되는 버퍼를 백 버퍼라고 부른다면에 보이는 버퍼를 프론트 버퍼 렌더링 되는 버퍼를 백 버퍼라고 부른다
- 버퍼를 2개 대신 3개를 사용하면 트리플 버퍼링 (Triple Buffering)이라고 한다
- 한 프레임을 렌더링 하는데 필요한 렌더 루프를 다시 정리하면 다음 그림과 같다

- 프레임이 시작되고 씬을 렌더링 하기 전에 물리, 입력 로직, 애니메이션 등의 연산이 업데이트 과정에서 일어난다
- 그 후 불필요한 렌더링 부하를 바지하기 위해 컬링 연산이 이루어진다
- 그 후 그려져야 하는 씬 오브젝트들을 렌더링한다 각 오브젝트들 마다 드로우콜이 발생하며 버텍스 쉐이더와 프래그먼트 쉐이더 등의 GPU파이프라인을 거쳐 버퍼에 순차적으로 렌더링 된다
- 씬의 오브젝트들을 렌더링하고 나서 블룸이나 컬러그레이딩 등의 포스트 프로세싱을 처리한다
포스트 프로세싱은 특정 오브젝트의 메시를 그리는 대신 화면을 덮는 사각형을 그려서 대부분 버텍스 쉐이더에서 처리된다
각 오브젝트마다 효과를 적용하지 않고 처리가 끝난 화면전체를 통짜로 쉐이더 처리 해준다는 의미인 것 같다
- 렌더링이 끝나고 나면 디스플레이 해준다
현재 프레임이 렌더링되고 있는 백 버퍼는 프론트 버퍼로 교체되어 화면에 디스플레이되고, 기존의 프론트 버퍼는 다음 프레임을 렌더링하기 위한 백 버퍼가 되는 과정을 통해 연속되는 프레임을 원활하게 디스플레이 한다
3장에서 계속...