컴퓨터 그래픽스에서 3차원 가상 세계를 2차원 화면에 표시하는 과정은 렌더링(Rendering)이라 불리며, 이 렌더링을 수행하는 가장 보편적이고 효율적인 기술 중 하나가 바로 래스터라이제이션(Rasterization)이다. 이 기술의 핵심을 이해하기 위해서는 먼저 ‘래스터(Raster)’라는 개념을 명확히 해야 한다.
래스터란 현대의 모든 디지털 디스플레이를 구성하는 기본 캔버스로, 이미지를 표현하기 위해 화상 정보를 2차원 배열 형태의 픽셀(Pixel, Picture Element)로 구성한 것을 의미한다.1 즉, 래스터는 격자 형태로 배열된 연속된 픽셀들의 집합이다. 우리가 보는 모니터, 스마트폰 화면 등은 모두 이러한 픽셀 격자로 이루어져 있으며, 각 픽셀에 특정 색상 값을 할당함으로써 최종 이미지가 형성된다.
래스터라이제이션이라는 용어는 독일어 ‘Raster’(골격, 틀)에서 유래했으며, 이는 라틴어 ‘rāstrum’(갈퀴, 긁개)에 뿌리를 두고 있다.3 이 어원은 기술의 본질을 직관적으로 설명하는 강력한 비유를 제공한다. 래스터라이제이션은 마치 갈퀴로 흙을 긁어 모양을 만들듯, 3차원 공간에 정의된 기하학적 데이터를 2차원 픽셀 격자 위로 ‘긁어서’ 어떤 픽셀들이 해당 기하학적 형태에 의해 ‘덮이는지’를 결정하는 과정이다.
래스터라이제이션의 근본적인 과제는 3차원 객체의 벡터(Vector) 기반 표현을 2차원 래스터 이미지로 변환하는 것이다.2 3D 모델은 수학적으로 정의된 점(Vertex), 선(Edge), 면(Polygon)의 집합, 즉 벡터 데이터로 구성된다. 래스터라이제이션은 이러한 추상적인 기하학 정보를 가져와 화면의 물리적인 픽셀 격자에 투영하고 채우는 구체적인 작업이다. 이 접근 방식은 ‘객체 순서(Object-Order)’ 처리 철학을 따르는데, 이는 씬(Scene)의 각 객체를 순서대로 가져와 화면에 그려나가는 방식을 의미한다.
래스터라이제이션 과정의 입력 데이터는 점(Point), 선(Line), 그리고 가장 중요한 삼각형(Triangle)과 같은 기하학적 기본 단위, 즉 프리미티브(Primitive)다.5 복잡한 3D 모델은 렌더링 파이프라인에 들어가기 전에 거의 예외 없이 수많은 삼각형의 집합인 메시(Mesh)로 분해된다. 따라서 3D 래스터라이제이션이 풀어야 할 가장 중심적인 문제는 ‘삼각형을 래스터화하는 방법’이다.3
삼각형이 보편적으로 사용되는 이유는 그것이 기하학적으로 가장 단순하고 안정적인 다각형이기 때문이다. 임의의 세 개의 정점은 항상 하나의 평면을 정의하므로, 표면 법선(Normal), 면적, 보간(Interpolation)과 같은 계산이 매우 단순하고 예측 가능해진다. 이러한 단순성은 대규모 병렬 처리를 수행하는 GPU(Graphics Processing Unit)의 하드웨어 구현에 있어 절대적으로 중요하다.
래스터라이제이션 과정은 반드시 결정적(Deterministic)이어야 한다. 즉, 동일한 입력에 대해 항상 동일한 출력을 보장해야 한다. 만약 인접한 두 삼각형이 공유하는 경계선 위의 픽셀을 처리하는 규칙이 명확하지 않다면, 렌더링 순서에 따라 픽셀이 누락되거나(틈 발생) 중복으로 그려져(겹침 발생) 시각적 결함(Artifact)을 유발할 수 있다.3
이 문제를 해결하기 위해 ‘탑-레프트 규칙(Top-Left Rule)’과 같은 일관된 스캔 변환 규칙이 사용된다. 이 규칙은 Direct3D 및 다수의 OpenGL 구현에서 채택하고 있으며, 다음과 같이 정의된다 3:
이러한 규칙은 두 인접 삼각형이 경계선을 공유할 때, 해당 경계선 위의 픽셀이 단 하나의 삼각형에 의해서만 렌더링되도록 보장한다. 이는 픽셀이 두 번 이상 래스터화되는 것을 방지하여 계산 낭비를 줄이고 3, GPU의 수많은 코어가 어떤 순서로 병렬 처리하더라도 항상 일관되고 틈이 없는(hole-free) 최종 이미지를 생성하는 기반이 된다. 따라서 이 규칙은 단순한 구현 세부사항이 아니라, 병렬 하드웨어 환경에서 시각적 일관성을 보장하는 소프트웨어 API와 하드웨어 간의 근본적인 약속이다.
현대의 실시간 3D 렌더링은 단일 칩의 독자적인 작업이 아니라, 중앙 처리 장치(CPU)와 그래픽 처리 장치(GPU) 간의 긴밀한 협력을 통해 이루어진다. 이 협력 관계와 렌더링 파이프라인의 구조적 진화를 이해하는 것은 래스터라이제이션의 작동 방식을 파악하는 데 필수적이다.
렌더링 과정은 본질적으로 분업화된 파트너십이다. CPU는 애플리케이션의 상위 레벨 로직, 씬 관리, 물리 시뮬레이션, 그리고 렌더링할 객체를 선별하는 컬링(Culling) 연산 등을 담당한다.4 CPU는 이러한 준비 작업을 마친 후, 렌더링에 필요한 데이터(정점 정보, 텍스처, 재질 등)와 그리기 명령(Draw Call)을 GPU로 전송한다. 그러면 GPU는 고도로 병렬화된 자체 파이프라인을 통해 이 명령들을 실행하여 최종 이미지를 생성한다.4 이러한 역할 분담은 각 프로세서가 가장 잘하는 작업에 집중하게 함으로써 실시간 프레임 속도를 달성하는 데 결정적인 역할을 한다.
초기 3D 그래픽스 하드웨어는 ‘고정 함수 파이프라인(Fixed-Function Pipeline, FFP)’ 구조를 가졌다. 이 파이프라인은 하드웨어에 미리 정의된 제한된 수의 기능(예: 특정 조명 모델, 정해진 변환 방식)만을 제공했으며, 개발자는 단지 이 기능들을 설정하고 조합하는 것만 가능했다.7 이는 창의적인 시각 효과 구현에 큰 제약으로 작용했다.9
그래픽 기술의 혁명은 ‘프로그래머블 셰이더(Programmable Shader)’의 등장과 함께 시작되었다. 셰이더는 GPU 상에서 직접 실행되는 작은 프로그램으로, 개발자가 파이프라인의 특정 단계를 직접 코드로 제어할 수 있게 해준다.11 DirectX 8.0과 OpenGL 2.0을 기점으로 도입된 버텍스 셰이더(Vertex Shader)와 픽셀 셰이더(Pixel Shader)는 개발자에게 정점(Vertex)과 픽셀(Pixel) 수준의 처리 과정을 완벽하게 제어할 수 있는 권한을 부여했다.10 이로 인해 고정된 기능의 한계를 넘어 무한에 가까운 시각적 효과를 창출할 수 있게 되었고, 이는 현대 컴퓨터 그래픽스의 폭발적인 발전을 이끌었다. 현재의 GPU는 오래된 고정 함수 API 호출을 내부적으로 셰이더를 이용해 에뮬레이션하여 호환성을 유지한다.14
렌더링 파이프라인의 전체 데이터 흐름은 다음과 같이 요약할 수 있다. 먼저 애플리케이션(주로 CPU에서 실행)이 3D 모델의 정점 데이터를 정점 버퍼(Vertex Buffer)에 채워 넣는다. 이 데이터는 GPU로 전송되어 파이프라인의 첫 단계인 입력 조립기(Input Assembler)를 통해 처리된다. 이후 여러 지오메트리 처리 단계를 거치며 3D 공간의 좌표가 2D 화면 좌표로 변환된다. 래스터라이저(Rasterizer)는 변환된 기하학 정보를 픽셀 조각인 프래그먼트(Fragment)로 변환하고, 프래그먼트 셰이더가 각 프래그먼트의 최종 색상을 계산한다. 마지막으로 출력 병합기(Output Merger)에서 깊이 테스트와 블렌딩 등을 거쳐 최종 픽셀 색상이 프레임버퍼(Framebuffer)에 기록되고, 이 프레임버퍼의 내용이 화면에 표시된다.1
아래 표는 현대 프로그래밍 가능 그래픽스 파이프라인의 각 단계를 요약한 것이다. 이는 이어질 상세 설명의 로드맵 역할을 하며, 각 단계의 핵심 기능, 입출력 데이터, 그리고 프로그래밍 가능 여부를 명확히 보여준다.
| 단계 이름 | 핵심 기능 | 입력 | 출력 | 프로그래밍 가능 여부 |
|---|---|---|---|---|
| 입력 조립기 (Input Assembler) | 정점 데이터로부터 프리미티브(삼각형 등) 구성 | 정점/인덱스 버퍼 | 프리미티브 | 고정 함수 |
| 버텍스 셰이더 (Vertex Shader) | 정점의 좌표 변환 및 기타 정점별 연산 | 개별 정점 | 변환된 정점 | 프로그래밍 가능 |
| 헐 셰이더 (Hull Shader) | 테셀레이션 수준 및 제어점 정의 | 제어점 패치 | 변환된 제어점, 테셀레이션 계수 | 프로그래밍 가능 |
| 테셀레이터 (Tessellator) | 정의된 수준에 따라 프리미티브 세분화 | 테셀레이션 계수 | 새로운 샘플링 포인트 | 고정 함수 |
| 도메인 셰이더 (Domain Shader) | 세분화된 정점의 최종 위치 계산 | 샘플링 포인트, 제어점 패치 | 변환된 정점 | 프로그래밍 가능 |
| 지오메트리 셰이더 (Geometry Shader) | 프리미티브 생성, 수정, 파괴 | 프리미티브 | 0개 이상의 프리미티브 | 프로그래밍 가능 |
| 래스터라이저 (Rasterizer) | 프리미티브를 프래그먼트로 변환 (클리핑, 컬링 등 포함) | 변환된 프리미티브 | 프래그먼트 | 고정 함수 |
| 프래그먼트 셰이더 (Fragment Shader) | 프래그먼트(픽셀)의 최종 색상 계산 (텍스처링, 조명) | 보간된 프래그먼트 데이터 | 프래그먼트 색상 및 깊이 | 프로그래밍 가능 |
| 출력 병합기 (Output Merger) | 프래그먼트를 프레임버퍼와 병합 (깊이/스텐실 테스트, 블렌딩) | 프래그먼트 색상 및 깊이 | 최종 픽셀 색상 | 고정 함수 |
파이프라인의 전반부는 주로 3D 모델의 기하학적 정보, 즉 ‘무엇을(What)’ ‘어디에(Where)’ 그릴 것인지를 결정하는 데 집중한다. 이 단계들은 정점(Vertex) 데이터를 입력받아 화면에 표시될 최종 형태로 가공하는 역할을 수행한다.
입력 조립기는 파이프라인의 가장 첫 번째 고정 함수 단계이다. 이 단계의 역할은 CPU가 메모리에 준비해 둔 정점 데이터(위치, 색상, 법선, 텍스처 좌표 등)를 읽어오는 것이다.15 이 데이터는 보통 정점 버퍼(Vertex Buffer)와 인덱스 버퍼(Index Buffer)라는 두 가지 형태로 제공된다. 정점 버퍼는 각 정점의 속성 정보를 담고 있으며, 인덱스 버퍼는 이 정점들을 어떤 순서로 연결하여 프리미티브(예: 삼각형)를 만들지를 정의한다. IA는 이 정보들을 바탕으로 지정된 프리미티브들을 조립하여 다음 단계인 버텍스 셰이더로 전달한다.16
버텍스 셰이더는 파이프라인에서 만나는 첫 번째 프로그래밍 가능 단계이며, 그 역할은 지대하다. 이 셰이더는 입력 조립기로부터 전달받은 각 정점에 대해 개별적으로 한 번씩 실행된다.11
버텍스 셰이더의 가장 핵심적이고 필수적인 임무는 좌표 공간 변환(Coordinate Space Transformation)이다.4 3D 모델의 정점들은 처음에는 모델 자체의 원점을 기준으로 하는 로컬 공간(Local Space)에 정의되어 있다. 버텍스 셰이더는 일련의 행렬 곱셈을 통해 이 좌표들을 변환한다.
이 모든 변환은 보통 하나의 행렬, 즉 모델-뷰-투영(Model-View-Projection, MVP) 행렬을 정점 좌표에 곱함으로써 효율적으로 수행된다. 이 외에도 버텍스 셰이더는 정점 단위 조명 계산(예: 고러드 셰이딩), 캐릭터 애니메이션을 위한 스키닝(Skinning) 등 다양한 정점별 연산을 수행할 수 있다.
테셀레이션은 DirectX 11과 OpenGL 4.0에서 도입된 선택적 단계로, GPU가 동적으로 지오메트리를 세분화할 수 있게 해주는 강력한 기능이다.19 이 단계는 세 부분으로 구성된다.
테셀레이션의 주된 용도는 동적 상세 수준(Level of Detail, LOD) 구현이다. 카메라에서 가까운 객체는 매우 정교하게 세분화하여 디테일을 높이고, 멀리 있는 객체는 단순한 형태로 유지함으로써 시각적 품질과 성능 사이의 균형을 맞출 수 있다.20
지오메트리 셰이더는 파이프라인 중간에서 프리미티브 단위를 통째로 생성하거나 제거할 수 있는 선택적 프로그래밍 단계이다.18 입력으로 하나의 프리미티브(예: 삼각형 하나)를 받아 0개, 1개, 또는 여러 개의 새로운 프리미티브를 출력할 수 있다. 예를 들어, 모든 삼각형의 법선 벡터를 시각적으로 표시하거나, 정점에서 머리카락이나 풀잎 같은 지오메트리를 생성(Extrude)하는 데 사용될 수 있다. 강력한 기능이지만, 출력되는 데이터 양의 변동성이 커서 GPU 파이프라인에 병목 현상을 일으킬 수 있으므로 다른 셰이더 단계에 비해 신중하게 사용된다.
지오메트리 처리 단계에서 ‘무엇을 어디에’ 그릴지가 결정되면, 파이프라인의 후반부는 ‘어떻게(How)’ 그릴지를 담당한다. 이 단계들은 3차원 기하학 정보를 최종적인 2차원 픽셀 색상으로 변환하는 핵심적인 역할을 수행한다.
래스터라이저는 프로그래밍이 불가능한 핵심적인 고정 함수 하드웨어 단계이다.15 이 단계는 지오메트리 단계에서 넘어온 클립 공간의 프리미티브(주로 삼각형)를 입력받아, 화면에 표시될 픽셀들의 집합인 프래그먼트(Fragment)로 변환하는 역할을 한다. 이 과정은 여러 개의 중요한 하위 작업으로 구성된다.
클리핑 (Clipping): 뷰 프러스텀(View Frustum), 즉 카메라의 시야각에 의해 정의되는 잘린 피라미드 형태의 3D 공간 외부에 완전히 벗어난 프리미티브는 버려진다. 프러스텀 경계에 걸쳐 있는 프리미티브는 경계면을 따라 잘리고, 내부에 있는 부분만 유지된다. 이 과정을 통해 화면에 보이지 않는 지오메트리를 조기에 제거한다.15
원근 분할 (Perspective Division): 클립 공간의 4차원 동차 좌표 $(x, y, z, w)$를 네 번째 성분인 w로 나누어 정규화된 장치 좌표(Normalized Device Coordinates, NDC)로 변환한다 (x/w,y/w,z/w).15 이 과정을 통해 원근 투영이 완료되어,
w값이 클수록(카메라에서 멀수록) 객체가 작게 보이게 된다. NDC 공간에서 x,y,z 좌표는 보통 -1에서 1 또는 0에서 1 사이의 범위를 갖는다.
후면 컬링 (Back-Face Culling): 매우 중요한 최적화 기법이다. 닫힌 객체(예: 구, 상자)의 경우, 카메라를 등지고 있는 삼각형 면들은 어차피 보이지 않는다. 후면 컬링은 삼각형의 표면 법선 벡터(면이 향하는 방향)와 카메라의 시선 벡터를 비교하여, 시선 방향과 반대인 후면(Back-face)들을 렌더링 과정에서 완전히 제외시킨다.15 이로써 처리해야 할 폴리곤의 수를 절반 가까이 줄일 수 있다.
뷰포트 변환 (Viewport Transformation): NDC 공간의 좌표(-1에서 1 범위)를 실제 화면의 픽셀 좌표(예: 가로 0~1920, 세로 0~1080)로 변환한다.15 이 변환을 통해 3차원 좌표가 최종적인 2차원 화면 좌표로 사상(Mapping)된다. 이 과정에서
z값은 깊이 정보로 유지되어 이후 깊이 테스트에 사용된다.
스캔 변환 (Scan Conversion): 뷰포트 변환을 거친 2차원 삼각형이 어떤 픽셀 중심점을 덮고 있는지 판별하는 과정이다. 래스터라이저는 삼각형 내부에 포함되는 모든 픽셀에 대해 ‘프래그먼트’를 생성한다.15 프래그먼트는 최종 픽셀이 되기 전의 잠재적 픽셀 데이터로, 위치 정보와 함께 정점에서 보간된 속성 값(색상, 텍스처 좌표 등)을 포함한다.
프래그먼트 셰이더는 파이프라인의 두 번째 주요 프로그래밍 가능 단계로, GPU 성능에 가장 큰 영향을 미치는 부분 중 하나이다.1 이 셰이더는 래스터라이저가 생성한 모든 프래그먼트에 대해 한 번씩 실행되며, 해당 프래그먼트의 최종 색상을 결정하는 역할을 한다.11 DirectX에서는 ‘픽셀 셰이더’라고 부르지만, OpenGL에서는 ‘프래그먼트 셰이더’라는 용어를 사용한다.
프래그먼트 셰이더에서 수행되는 주요 작업은 다음과 같다.
프래그먼트 셰이더는 최종적으로 계산된 색상(RGBA) 값과 깊이(z) 값을 다음 단계인 출력 병합기로 전달한다.
출력 병합기는 파이프라인의 마지막 고정 함수 단계로, 프래그먼트 셰이더에서 넘어온 결과물을 프레임버퍼(Framebuffer)에 기록하는 역할을 한다.15 프레임버퍼는 화면에 표시될 최종 이미지의 색상 정보를 담는 컬러 버퍼(Color Buffer)와 각 픽셀의 깊이 정보를 담는 깊이 버퍼(Depth Buffer) 등으로 구성된다.
이 모든 테스트와 블렌딩 과정을 통과한 최종 픽셀 색상만이 컬러 버퍼에 기록되고, 렌더링이 완료된 프레임버퍼는 화면 표시 장치로 전송되어 우리가 보는 최종 이미지가 된다.1
현대 래스터라이제이션 파이프라인은 그 자체만으로는 사실적인 이미지를 효율적으로 생성할 수 없다. 파이프라인의 각 단계를 지원하고 그 성능과 품질을 극대화하는 여러 핵심 알고리즘들이 존재한다. 이 장에서는 그중 가장 필수적인 기술인 깊이 버퍼링, 셰이딩 모델, 그리고 앤티에일리어싱에 대해 심도 있게 다룬다.
3D 씬을 2D 화면에 렌더링할 때 가장 근본적인 문제 중 하나는 ‘무엇이 보이고 무엇이 가려지는가’를 결정하는 ‘숨은 면 제거(Hidden Surface Removal)’ 문제이다. 이 문제를 효율적으로 해결하기 위해 현대 그래픽스에서는 거의 보편적으로 깊이 버퍼링(Depth Buffering) 기법을 사용한다.
Z-버퍼는 깊이 버퍼(Depth Buffer)라고도 불리며, 화면의 각 픽셀에 대한 깊이 정보, 즉 카메라로부터의 거리 값을 저장하는 2차원 메모리 배열이다.4 Z-버퍼의 크기는 컬러 버퍼와 동일하며, 각 픽셀 위치에 해당하는 Z-버퍼의 요소는 해당 픽셀에 마지막으로 그려진 객체의 정규화된 깊이 값(보통 0.0에서 1.0 사이)을 저장한다.
Z-버퍼링의 작동 원리는 매우 간단하면서도 강력하다.24
이 방식은 렌더링 순서에 의존하지 않고 픽셀 단위로 가시성을 판별할 수 있게 해준다. 이는 화가가 먼 배경부터 그리고 가까운 물체를 덧칠하는 방식인 ‘화가 알고리즘(Painter’s Algorithm)’과 같은 구식 기법들이 가진 순환 종속성 문제를 해결한 혁신적인 방법이었다.27
Z-버퍼는 유한한 비트 수(예: 16, 24, 32비트)로 깊이 값을 표현하기 때문에 정밀도에 한계가 있다. 이로 인해 ‘Z-파이팅(Z-Fighting)’이라는 시각적 결함이 발생할 수 있다.23 Z-파이팅은 거의 동일한 깊이를 가진 두 개 이상의 평면이 겹쳐 있을 때, Z-버퍼의 정밀도 한계로 인해 어떤 면이 앞에 있는지 일관되게 결정하지 못하여 픽셀들이 깜빡이거나 줄무늬 패턴(스티칭)이 나타나는 현상이다.
이 문제는 Z-버퍼의 깊이 값이 비선형적으로 분포하기 때문에 더욱 심화된다. 투영 변환의 수학적 특성상, Z-버퍼의 정밀도는 카메라에 가까운 근접 클리핑 평면(Near Clipping Plane) 근처에서 가장 높고, 멀리 있는 원거리 클리핑 평면(Far Clipping Plane)으로 갈수록 급격히 낮아진다.24 따라서 근접 평면과 원거리 평면 사이의 거리 비율(
far/near)이 클수록 원거리에서의 정밀도 손실이 커져 Z-파이팅이 발생할 확률이 높아진다.28
Z-파이팅을 완화하는 주된 방법은 다음과 같다.
Z-테스트는 중요한 성능 최적화 기회도 제공한다. 전통적으로 깊이 테스트는 프래그먼트 셰이더가 실행된 후 출력 병합기 단계에서 수행되었다. 하지만 만약 어떤 프래그먼트가 다른 객체에 의해 완전히 가려질 것이 확실하다면, 비싼 연산이 포함된 프래그먼트 셰이더를 실행하는 것은 자원 낭비이다.
‘Early-Z’ (또는 Early Depth Test)는 이러한 낭비를 막기 위해 깊이 테스트를 프래그먼트 셰이더 이전에 수행하는 최적화 기법이다.1 만약 프래그먼트가 깊이 테스트에 실패하면, GPU는 즉시 해당 프래그먼트를 버리고 셰이더 실행을 건너뛴다. 이는 특히 화면에 겹쳐진 객체가 많은 복잡한 씬에서 엄청난 성능 향상을 가져온다. 더 나아가 현대 GPU는 ‘계층적 Z-버퍼(Hierarchical Z-Buffer, Hi-Z)’를 사용하여, 픽셀 블록 단위로 가시성을 빠르게 판별하고 가려진 영역 전체를 한 번에 컬링함으로써 성능을 더욱 극대화한다.
셰이딩(Shading)은 빛과 표면의 상호작용을 계산하여 객체의 색상과 명암을 결정하는 과정이다. 래스터라이제이션은 셰이딩 모델을 통해 평평한 삼각형에 입체감과 사실감을 부여한다.
퐁 셰이딩 모델은 1970년대에 부이 뜨엉 퐁(Bui Tuong Phong)에 의해 개발된 고전적이면서도 영향력 있는 조명 모델이다.29 이 모델은 조명을 세 가지 구성 요소로 분해하여 계산의 복잡성과 시각적 사실성 사이의 균형을 맞춘다.30
블린-퐁(Blinn-Phong) 모델은 퐁 모델의 정반사광 계산을 최적화한 버전이다. 반사 벡터를 계산하는 대신, 광원 벡터와 뷰 벡터의 중간 지점에 있는 ‘하프웨이 벡터(Halfway Vector)’를 사용한다.31 하프웨이 벡터와 표면 법선 벡터를 비교하는 것이 계산적으로 더 저렴하기 때문에, 블린-퐁 모델은 퐁 모델과 거의 유사한 결과를 더 빠른 속도로 제공하여 널리 사용되었다.
초기 3D 그래픽스에서는 ‘고러드 셰이딩(Gouraud Shading)’이 주로 사용되었다. 이 방식은 각 삼각형의 정점(Vertex)에서만 조명을 계산하고, 그 결과로 나온 색상 값을 삼각형 내부로 선형 보간(Linearly Interpolate)하여 채웠다.32 이 방식은 계산이 빠르다는 장점이 있었지만, 정반사 하이라이트처럼 삼각형 중간에 나타나야 하는 세밀한 조명 효과를 표현할 수 없었고, 하이라이트가 정점 근처에 있을 때만 부정확하게 나타나는 문제가 있었다.
프로그래머블 셰이더의 등장으로 ‘퐁 셰이딩(Phong Shading)’ 기법이 가능해졌다. 여기서 퐁 셰이딩은 조명 모델(Phong reflection model)과 다른, 보간 기법을 의미한다. 이 방식은 정점에서 색상이 아닌 법선 벡터를 보간하고, 래스터화된 모든 픽셀(프래그먼트)에 대해 프래그먼트 셰이더 내에서 조명을 다시 계산한다.22 이 ‘픽셀 단위(Per-pixel)’ 조명 계산은 삼각형의 크기에 상관없이 매끄럽고 정확한 정반사 하이라이트를 생성할 수 있게 해주었으며, 이는 실시간 그래픽 품질의 비약적인 발전을 가져온 중요한 전환점이었다.
래스터라이제이션은 본질적으로 연속적인 기하학적 형태(선, 삼각형의 경계)를 불연속적인 픽셀 격자로 표현하는 과정이다. 이 과정에서 ‘에일리어싱(Aliasing)’, 흔히 “계단 현상(Jaggies)”이라 불리는 시각적 결함이 발생한다.35 이는 부드러운 대각선이나 곡선이 픽셀 격자 위에서 톱니 모양으로 거칠게 표현되는 현상이다. 앤티에일리어싱(Anti-Aliasing, AA)은 이러한 계단 현상을 완화하여 이미지를 더 부드럽고 자연스럽게 만드는 기술들의 총칭이다.
다양한 AA 기술들은 그 작동 원리와 성능/품질 트레이드오프에 따라 크게 세 가지 범주로 나눌 수 있다.
| 기술 | 작동 방식 (Method) | 성능 비용 | 시각적 품질 (장점) | 시각적 결함 (단점) |
|---|---|---|---|---|
| SSAA | 전체 화면을 고해상도로 렌더링 후 다운샘플링 | 매우 높음 | 가장 완벽한 AA 품질. 텍스처 에일리어싱까지 제거. | 극심한 성능 저하. 실시간 적용 거의 불가능. |
| MSAA | 폴리곤 경계선에서만 다중 샘플링 수행 | 중간 ~ 높음 | 우수한 기하학적 에일리어싱 제거. 선명한 텍스처 유지. | 텍스처 내부 에일리어싱, 투명 텍스처 에일리어싱은 처리 못 함. |
| FXAA | 후처리 방식으로 이미지의 경계선을 감지하여 블러링 | 매우 낮음 | 성능 저하가 거의 없음. 모든 종류의 에일리어싱에 적용 가능. | 이미지 전체가 다소 흐릿해짐. 특히 텍스처 디테일 손상. |
| TAA | 이전 프레임 정보를 활용하여 현재 프레임 보정 | 낮음 | 움직임 중 발생하는 반짝임(Shimmering) 제거에 매우 효과적. | 빠른 움직임에서 잔상(Ghosting) 및 블러 현상 발생 가능. |
수십 년간 실시간 렌더링의 왕좌를 지켜온 래스터라이제이션에게 최근 강력한 경쟁자가 등장했다. 바로 레이 트레이싱(Ray Tracing, 광선 추적)이다. 두 기술은 단순히 방법론만 다른 것이 아니라, 이미지를 생성하는 근본적인 철학에서부터 차이를 보인다. 이 장에서는 두 기술의 차이점을 분석하고, 실시간 그래픽스의 미래를 조망한다.
래스터라이제이션과 레이 트레이싱의 가장 근본적인 차이는 처리 순서에 있다.
객체 순서(Object-Order) vs. 이미지 순서(Image-Order):
속도를 위한 근사 vs. 정확성을 위한 시뮬레이션:
이러한 철학적 차이는 두 기술의 핵심적인 트레이드오프로 이어진다.
두 기술의 차이는 반사, 그림자, 전역 조명과 같이 빛의 복잡한 상호작용을 표현할 때 극명하게 드러난다.
| 기능 | 래스터라이제이션 접근법 | 레이 트레이싱 접근법 | 핵심 차이점 (성능 vs. 충실도) |
|---|---|---|---|
| 반사 | 큐브맵, SSR 등 ‘트릭’ 사용. 화면 내 정보만으로 근사. | 반사 광선을 물리적으로 추적. | 성능: 래스터라이제이션이 훨씬 빠름. 충실도: 레이 트레이싱은 화면 밖 객체, 상호 반사 등 물리적으로 정확한 결과를 제공. |
| 그림자 | 섀도 매핑. 깊이 맵을 이용한 근사. | 그림자 광선을 쏘아 가려짐 여부 판별. | 성능: 섀도 매핑이 빠름. 충실도: 레이 트레이싱은 에일리어싱이 없고, 물리적으로 정확한 부드러운 그림자(Soft Shadow)를 자연스럽게 생성. |
| 전역 조명 | 주로 라이트맵에 미리 ‘베이킹’. 실시간 근사는 SSAO 등으로 제한. | 광선이 여러 번 튕기는 것을 시뮬레이션 (패스 트레이싱). | 성능: 베이킹은 실시간 비용이 없으나 동적이지 않음. 충실도: 레이 트레이싱은 동적인 간접광과 색 번짐 현상을 사실적으로 표현. |
레이 트레이싱의 압도적인 시각적 품질에도 불구하고, 래스터라이제이션이 가까운 미래에 완전히 사라질 가능성은 낮다. 대신, 실시간 그래픽스의 미래는 두 기술의 장점을 결합한 하이브리드 렌더링(Hybrid Rendering) 모델로 나아가고 있다.52
하이브리드 모델에서 래스터라이제이션은 그 자체의 압도적인 속도를 활용하여 씬의 기본적인 가시성(Visibility)과 지오메트리를 처리하는 기반 역할을 한다.52 즉, 화면의 대부분을 빠르게 렌더링하는 주력 엔진으로 사용된다. 그 위에, 래스터라이제이션만으로는 표현하기 어려운 특정 효과들, 예를 들어 거울의 정확한 반사, 투명한 유리의 굴절, 부드러운 그림자, 사실적인 간접 조명 등을 레이 트레이싱을 통해 선택적으로 추가하는 방식이다.52
이러한 하이브리드 접근법을 현실로 만든 핵심 동력은 AI 기반 업스케일링 기술이다. NVIDIA의 DLSS(Deep Learning Super Sampling)나 AMD의 FSR(FidelityFX Super Resolution)과 같은 기술들은 레이 트레이싱으로 인해 무거워진 렌더링 작업을 더 낮은 해상도에서 수행한 뒤, AI 알고리즘을 통해 목표 해상도로 지능적으로 업스케일링한다.50 이를 통해 레이 트레이싱의 막대한 성능 비용을 상쇄하면서도 고품질의 최종 이미지를 실시간 프레임 속도로 얻을 수 있게 되었다. 결국, 미래의 실시간 렌더링은 래스터라이제이션의 효율성과 레이 트레이싱의 사실성을 모두 취하는, 가장 실용적인 방향으로 진화하고 있다.
래스터라이제이션은 정적인 기술이 아니다. 지난 수십 년간 하드웨어의 발전과 소프트웨어의 혁신 속에서 끊임없이 진화해왔으며, 현재도 새로운 도전과 기회에 직면하며 변화를 거듭하고 있다. 이 장에서는 래스터라이제이션의 역사적 발자취를 돌아보고, 현재와 미래의 기술 동향을 탐구한다.
1990년대 초중반의 3D 그래픽스는 극심한 하드웨어 제약 속에서 태동했다. 당시의 PC는 처리할 수 있는 폴리곤(삼각형)의 수가 매우 적었고, 텍스처를 저장할 메모리도 부족했다. 하지만 가장 큰 병목은 필레이트(Fill Rate)와 메모리 대역폭(Memory Bandwidth)이었다.54 필레이트는 GPU가 1초에 화면에 그릴 수 있는 픽셀의 총량을, 메모리 대역폭은 GPU가 메모리로부터 데이터를 얼마나 빨리 가져오고 쓸 수 있는지를 나타낸다. 이 두 가지 성능 지표의 한계는 복잡한 셰이딩이나 높은 해상도의 렌더링을 불가능하게 만들었다.
이러한 제약 속에서 개발자들은 하드웨어의 한계를 극복하기 위한 창의적인 소프트웨어 기법을 고안해야 했다. 그 대표적인 사례가 1996년에 출시된 id Software의 퀘이크(Quake) 엔진이다.57 당시 하드웨어로는 동적인 실시간 조명을 모든 픽셀에 대해 계산하는 것이 불가능했다. 존 카맥(John Carmack)과 그의 팀은 이 문제를 해결하기 위해 라이트맵(Lightmap)이라는 혁신적인 기법을 도입했다.59
라이트맵은 씬의 정적인(움직이지 않는) 객체들에 대한 복잡한 조명과 그림자 정보를 미리 계산하여, 그 결과를 텍스처 이미지의 형태로 저장하는 방식이다. 게임이 실행될 때는 이 라이트맵을 객체의 기본 텍스처 위에 겹쳐 그리기만 하면 되었다. 이로써 실시간 성능 비용을 거의 들이지 않고도 매우 사실적이고 분위기 있는 정적 조명 효과를 구현할 수 있었다.62 라이트맵은 하드웨어의 한계를 소프트웨어적 창의성으로 극복한 대표적인 예시이며, 이후 수많은 게임 엔진에서 표준적인 기법으로 자리 잡았다.
1990년대 후반, 3D 그래픽 가속기, 즉 GPU(Graphics Processing Unit)가 등장하면서 실시간 그래픽스 환경은 근본적으로 변화하기 시작했다.63 초기 GPU는 고정 함수 파이프라인을 통해 렌더링 과정을 하드웨어적으로 가속했다.
진정한 혁명은 2000년대 초, DirectX 8/9와 OpenGL 2.0이 프로그래머블 셰이더를 도입하면서 시작되었다.9 이는 그래픽스 파이프라인의 핵심 단계(정점 및 픽셀 처리)를 개발자가 직접 프로그래밍할 수 있게 만든 패러다임의 전환이었다. 고정된 하드웨어 기능에 얽매이지 않고, 개발자가 원하는 독창적인 시각 효과를 무한히 구현할 수 있는 시대가 열린 것이다. 언리얼 엔진(Unreal Engine)과 크라이엔진(CryEngine) 같은 게임 엔진들은 이 새로운 기술을 적극적으로 활용하여, 이전과는 비교할 수 없는 수준의 시각적 복잡성과 사실성을 선보이며 그래픽 기술의 발전을 이끌었다.51
래스터라이제이션 기술은 정체되어 있지 않다. 데스크톱과 모바일이라는 서로 다른 하드웨어 생태계의 요구에 맞춰 각기 다른 방향으로 진화하고 있으며, 인공지능과 같은 새로운 분야와 융합하며 그 응용 범위를 넓혀가고 있다. 이는 단순히 그림을 더 빨리 그리는 것을 넘어, 렌더링 과정 자체를 더 지능적이고 다재다능하게 만드는 방향으로 나아가고 있음을 시사한다.
데스크톱 GPU가 ‘즉시 모드(Immediate Mode)’ 렌더링, 즉 삼각형을 받는 즉시 처리하여 프레임버퍼 전체에 그리는 방식을 사용하는 것과 달리, 대부분의 모바일 GPU는 타일 기반 렌더링(TBR)이라는 근본적으로 다른 아키텍처를 채택하고 있다. ARM의 Mali 69와 Qualcomm의 Adreno 72가 대표적이다.
TBR 아키텍처는 화면을 작은 사각형 ‘타일(Tile)’(예: 16x16 픽셀)로 분할한다.69 렌더링은 두 단계로 진행된다. 첫 번째 ‘비닝(Binning)’ 단계에서는 씬의 모든 지오메트리를 처리하여 각 타일에 어떤 삼각형들이 영향을 미치는지 목록을 작성한다. 두 번째 ‘렌더링’ 단계에서는 각 타일을 하나씩, GPU 내의 매우 빠른 온칩(On-chip) 메모리에 로드하여 해당 타일에 속한 삼각형들만 렌더링한다.74 타일 하나의 렌더링이 완료되면 그 결과만 외부의 느린 주 메모리(DRAM)로 내보낸다.
이 방식은 렌더링 과정에서 발생하는 막대한 양의 깊이 및 색상 데이터 읽기/쓰기를 온칩 메모리 내에서 해결함으로써, 전력 소모가 크고 성능 병목이 되기 쉬운 외부 메모리 접근을 극적으로 줄여준다.69 이러한 구조적 차이 때문에 모바일 환경에서의 그래픽 최적화 전략은 데스크톱과 크게 다르며, 메모리 대역폭을 절약하는 것이 핵심 과제가 된다.76
VRS는 비교적 최신 GPU에 도입된 기능으로, 렌더링 효율을 높이는 지능적인 최적화 기술이다. 전통적인 렌더링에서는 화면의 모든 픽셀을 개별적으로 셰이딩(색상 계산)했다. 하지만 VRS는 GPU가 픽셀 그룹(예: 2x2 또는 4x4 블록)을 단 한 번의 프래그먼트 셰이더 실행으로 처리하고, 그 결과를 블록 내의 모든 픽셀에 적용할 수 있게 해준다.80
핵심은 셰이딩 비율(Shading Rate)과 가시성 비율(Visibility Rate)을 분리한 것이다. 즉, 지오메트리의 경계는 원래 해상도로 정밀하게 계산하여 선명함을 유지하면서, 픽셀의 색상을 계산하는 셰이딩 작업의 빈도는 동적으로 조절할 수 있다. 개발자는 모션 블러가 적용된 영역, VR 헤드셋의 주변부, 어두운 영역 등 시각적으로 중요도가 낮은 부분의 셰이딩 비율을 낮춤으로써, 인지되는 품질 저하를 최소화하면서 상당한 성능 향상을 얻을 수 있다.82
미분 가능 렌더링은 래스터라이제이션을 그래픽스 영역을 넘어 인공지능(AI) 및 머신러닝(ML) 분야로 확장하는 최첨단 연구 분야이다.84 전통적인 렌더러는 입력(3D 모델, 카메라 위치 등)을 받아 출력(2D 이미지)을 생성하는, 미분이 불가능한 ‘블랙박스’와 같았다.
미분 가능 렌더러는 이 과정을 수학적으로 미분 가능하게 만듦으로써, 최종 이미지의 픽셀 값 변화에 대한 입력 파라미터(예: 정점 위치, 카메라 각도)의 변화율, 즉 그래디언트(Gradient)를 계산할 수 있게 한다.87 이는 렌더러를 경사 하강법(Gradient Descent)과 같은 최적화 루프의 일부로 사용할 수 있음을 의미한다.
이 기술은 다음과 같은 새로운 응용을 가능하게 한다:
미분 가능 렌더링은 렌더러의 역할을 순수한 시각화 도구에서, 물리 세계와 디지털 세계를 잇는 분석적이고 창의적인 도구로 재정의하며 래스터라이제이션 기술의 미래에 새로운 가능성을 열어주고 있다.
| 그래픽 파이프라인 - UWP applications | Microsoft Learn, accessed July 5, 2025, https://learn.microsoft.com/ko-kr/windows/uwp/graphics-concepts/graphics-pipeline |
| Z-버퍼링 이해하기: 알아야 할 모든 것 | 레노버 코리아 - Lenovo, accessed July 5, 2025, https://www.lenovo.com/kr/ko/glossary/z-buffering/ |
| 고해상도 렌더 파이프라인의 안티앨리어싱 | High Definition RP | 10.5.0, accessed July 5, 2025, https://docs.unity3d.com/kr/Packages/com.unity.render-pipelines.high-definition@10.5/manual/Anti-Aliasing.html |
| Anti aliasing | PPT - SlideShare, accessed July 5, 2025, https://www.slideshare.net/slideshow/anti-aliasing/12262298 |
| Games on the N64 are often limited by memory bandwidth, which is taken up by r… | Hacker News, accessed July 5, 2025, https://news.ycombinator.com/item?id=36501079 |
| John Carmack talk at Upper Bound 2025 | Hacker News, accessed July 5, 2025, https://news.ycombinator.com/item?id=44070042 |
| The Legendary Fast Inverse Square Root | by Shaw | Hard Mode - Medium, accessed July 5, 2025, https://medium.com/hard-mode/the-legendary-fast-inverse-square-root-e51fee3b49d9 |
| Quake Lightmaps | project log, accessed July 5, 2025, https://jbush001.github.io/2015/06/11/quake-lightmaps.html |
| Rendering Technologies from Crysis 3 (GDC 2013) | PPT - SlideShare, accessed July 5, 2025, https://www.slideshare.net/slideshow/rendering-technologies-from-crysis-3-gdc-2013/25052434 |
| Chapter 16. Vegetation Procedural Animation and Shading in Crysis | NVIDIA Developer, accessed July 5, 2025, https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-16-vegetation-procedural-animation-and-shading-crysis |
| Differentiable Vector Graphics Rasterization for Editing and Learning - People | MIT CSAIL, accessed July 5, 2025, https://people.csail.mit.edu/tzumao/diffvg/ |