Skip to content

3D 그래픽 개념 및 렌더링 파이프라인(1)

[칼럼 핵심 요약]
전회까지의 기사로, 최근에 이르는 3D 그래픽스의 대략적인 역사에 대해서는 이해해 주셨다고 생각한다. 이번에는 3D 그래픽 처리의 흐름을 배우자. 이번부터는 렌더링 파이프라인의 해설을 하고 싶다.

🌐 원문 링크: 3Dグラフィックスの概念とレンダリングパイプライン(1) (Mynavi News)
📅 원문 발행일: 2008-03-24 | ✍️ 저자: 西川善司 (니시카와 젠지 / Zenji Nishikawa)

NOTE

💡 현대 그래픽스 관점에서의 발전사 (Modern Retrospective)

  • 전통적 파이프라인의 재편: 버텍스 셰이더 → 지오메트리 셰이더 → 래스터라이저로 이어지던 전통적 파이프라인은 DX12 Ultimate / Vulkan에서 태스크 셰이더(Amplification/Task Shader) → 메시 셰이더(Mesh Shader) 파이프라인으로 대체되어, 지오메트리 컬링과 LOD 처리를 GPU 코어에서 고도로 병렬화하고 있습니다.
  • Draw Call 오버헤드 해소: 과거 CPU 병목의 주원인이었던 드로우 콜(Draw Call)은 모던 저수준 API(Vulkan, DirectX 12, Metal)의 바인드리스(Bindless) 렌더링과 GPU 구동 파이프라인(ExecuteIndirect / GPU-Driven Rendering)을 통해 수만 단위의 드로우를 단일 명령으로 처리합니다.

📖 본문 해설

[원문 리드문] > 전회까지의 기사로, 최근에 이르는 3D 그래픽스의 대략적인 역사에 대해서는 이해해 주셨다고 생각한다. 이번에는 3D 그래픽 처리의 흐름을 배우자. 이번부터는 렌더링 파이프라인의 해설을 하고 싶다.

여기 최근까지의 3D 그래픽스의 역사를 대략 이해한 곳에서, 이번은 3D 그래픽스의 처리의 흐름을 해설하고 싶다.

3D 그래픽 파이프라인의 개략도

3D 그래픽의 흐름을 모식화한 것이 그림 1이다. 이것은, DirectX 10세대/SM4 대응 GPU까지의 흐름을 모식화하고 있지만, 일부의 흐름의 순서는 GPU에 따라서 다른 경우나, 혹은 세세한 처리 페이즈에 대해서는 일부, 간략화하고 있는 부분도 있다. 이 점은 양해 바랍니다.

우선, 왜 3D 그래픽스 처리가 이렇게 되어 있는가 하는 근본적인 이야기에 대해서 접해 두자. 이렇게 되는 것은 길고 짧은 실시간 3D 그래픽의 역사 속에서 이것이 가장 처리가 원활하게 갈 것 같고, 또한 GPU(하드웨어) 설계로서 구현이 하기 쉽다는 이유 때문이다. 이 흐름은 Direct3D에서도 OpenGL에서도 큰 차이는 없다.

그림 1: GPU 내부의 렌더링 흐름그림 1: GPU 내부의 렌더링 흐름

🔍 [인포그래픽 도해 한국어 번역: GPU 내부 렌더링 흐름도]

  1. 버텍스 파이프라인: 3D 정점 데이터 입력 정점 좌표 변환 및 라이팅
  2. 지오메트리 셋업 & 래스터라이저: 폴리곤 구성 2D 픽셀 프래그먼트 생성 및 보간
  3. 픽셀 파이프라인: 텍스처 매핑 픽셀 단위 셰이딩 및 그림자 연산
  4. ROP (렌더 출력 유닛): Z-버퍼 깊이 테스트 알파 블렌딩 프레임 버퍼 출력

CPU가 담당하는 3D 그래픽 처리 부분 = 게임 엔진!?

그림 1에 있는 [1]과 [2]의 항목은, 이것은 주로 CPU에 의해 행해지는 처리계이다.

3D 오브젝트를 배치하거나, ​​이동해 재배치하거나…

게임엔진에서는 키 입력, 마우스 입력, 게임 컨트롤러 입력에 따라 3D 캐릭터를 이동시키거나 총격이 적에게 명중했는지의 충돌 판정을 하거나 충돌 결과, 3D 캐릭터끼리를 날리기 위한 물리 시뮬레이션을 하지만 그런 게임 로직의 부분은 어떤 의미, [1][2]에 해당하는 부분이다.

덧붙여 [2]는 DirectX 10/SM4.0 대응 GPU이면 지오메트리 쉐이더를 활용하면, GPU로 실시할 수도 있게 되어 있다. 예를 들면 파티클이나 빌보드와 같은 포인트 스프라이트에 대해서는 생성이나 소멸을 지오메트리 셰이더로 관리해, CPU를 개재시키지 않고 처리할 수 있다. 하지만 일반적인 3D 게임 처리 등에서는 아직 이 부분은 CPU가 담당하는 부분이라고 할 수 있다.

버텍스 파이프라인과 버텍스 쉐이더~좌표계란 무엇인가?

그림에서 빨간색 라인에 걸려 있는 [3][4][5][6] 부분이 버텍스 차원의 처리를 수행하는 버텍스 파이프라인이다.

통상은 여기로부터가 GPU 내부에서 처리가 행해지는 부분이 된다. 다만, 내부 로직을 간략화해 저비용으로 그래픽 기능을 통합시킨, 이른바 「통합 칩셋」등에서는, 이 버텍스 파이프라인을 CPU로 어깨 대신하는(에뮬레이션 하는) 시스템도 존재한다.

그런데, 조금 전까지는, 이 버텍스 파이프라인을 「지오메트리 처리」등이라고 부르는 일도 많았다. 지오메트리(Geometry)란 '기하학'으로, 고교생 이상이라면 수학으로 '대수·기하학' 등의 수업에서 '벡터 연산'이나 '맵과 1차 변환' 등을 배운 적이 있을지도 모르지만, 그 세계를 말한다. 여담이지만, NVIDIA의 GPU, GeForce 시리즈의 이름의 유래는 「Gemoteric Force(기하학적 힘)」를 줄인 조어로, 「G-Force(중력)」에 걸린 다자레가 되고 있다고 한다.

이야기를 되돌리면, 3D 그래픽스를 말하는데 있어서 반드시 등장하는 「3차원 벡터」라고 하는 개념은, 간단하게 말하면 「3차원 공간상의 "방향"」이라고 생각하면 된다. 그러한 "방향"은 x, y, z의 3축의 3개의 좌표치로 나타내고, 그 "방향"의 기준을 「좌표계」라고 한다.

이 좌표계에는 로컬 좌표계와 월드 좌표계(글로벌 좌표계)라는 것이 있다.

「로컬 좌표계」는, 구체적으로 말하면 어느 3D 캐릭터에 있어서 적당히 정한 기준이 되는 좌표계를 말한다. 3D 캐릭터의 방향은 그 3D 캐릭터 기준의 좌표계로 「어느쪽으로 향하고 있다」라고 관리해 제어하는 ​​것이 편하다. 그래서 로컬 좌표계라는 개념을 이용하는 것이다.

그런데, 일반적인 3D 캐릭터에는 팔이나 다리가 붙어 있는 경우가 많지만, 이것을 그 관절에서 구부리거나 하는 것을 생각했을 경우는, 관절을 기준으로 한 로컬 좌표계로 제어하는 ​​것이 알기 쉽다. 그러나 이런 식으로 생각하면 로컬 좌표계가 계층 구조가되어 최종적으로 처리를 정리할 때 번역을 알 수 없습니다.

따라서 3D 공간 전체를 지배하는 좌표계가 필요합니다. 그것이 '월드 좌표계'다. 3D 그래픽스의 버텍스 파이프라인 놓는 버텍스 단위의 처리에서는, 이 로컬 좌표계로부터 월드 좌표계로의 변환이 빈발한다.

이러한 버텍스 단위의 좌표계 변환 처리를, 셰이더 프로그램에 따라 실시하는 것이 [3]의 「버텍스 쉐이더」(Vertex Shader)인 것이다. 쉐이더 프로그램을 재조합하면 독특하고 특수한 좌표 변환을 할 수 있다는 것이다. (계속)

그림 2: 좌표계의 개념도그림 2: 좌표계의 개념도

(트라이Z 니시카와 젠지)


🔗 연관 지식 베이스 (Wiki)

Based on Zenji Nishikawa's 3D Graphics Maniax series. Translated & Knowledge-Based for Korean Game Developers.