게임 그래픽스 핵심 정리

게임 그래픽스는 단순히 화면에 예쁜 이미지를 출력하는 기술이 아니다.

게임에서 그래픽스는 CPU와 GPU가 데이터를 처리하고, 렌더링 파이프라인을 거쳐 최종적으로 화면에 픽셀을 출력하는 전체 과정을 의미한다.

게임 개발에서는 모델링이나 셰이더만 알아서는 부족하다.
프레임이 어떻게 만들어지는지, GPU가 어떤 작업을 수행하는지, 왜 특정 그래픽 옵션이 성능에 영향을 주는지 이해해야 한다.

전체적인 흐름은 다음과 같다.

Game Logic -> Scene Data -> Culling -> Rendering -> Lighting / Shadow -> Post Processing -> Anti-Aliasing -> Upscaling -> Display

GPU와 CPU

게임 그래픽스에서는 CPU와 GPU가 서로 다른 역할을 수행한다.

CPU는 게임 로직, 물리, 애니메이션, 렌더링 명령 생성 등의 작업을 담당하고 GPU는 실제 그래픽 연산을 병렬적으로 처리한다.

CPU -> Game Logic / Physics / Animation / Rendering Commands -> GPU -> Vertex Processing / Rasterization / Pixel Processing -> Frame

CPU가 GPU에게 렌더링할 내용을 전달하면 GPU가 이를 처리하여 최종 이미지를 생성한다.

따라서 게임 성능 문제는 단순히 GPU 성능만의 문제가 아니다.

CPU가 렌더링 명령을 너무 많이 생성하거나, GPU가 복잡한 셰이더와 고해상도 텍스처를 처리하느라 병목이 발생할 수도 있다.


Rendering Pipeline

렌더링 파이프라인은 3D 데이터를 최종 화면의 픽셀로 변환하는 과정이다.

Mesh / Material / Texture -> Vertex Processing -> Primitive Assembly -> Rasterization -> Fragment / Pixel Processing -> Framebuffer

Vertex Processing

3D 공간에 존재하는 정점(Vertex)을 화면에 표시할 수 있는 위치로 변환한다.

대표적으로 다음 변환이 발생한다.

Model Space -> World Space -> View Space -> Clip Space -> Screen Space

여기서 카메라의 위치와 방향, 오브젝트의 위치와 크기 등이 화면에 표시될 위치에 영향을 준다.

Rasterization

삼각형 형태의 3D 데이터를 화면의 픽셀 단위로 변환한다.

게임에서 사용하는 대부분의 3D 모델은 삼각형의 집합으로 구성되어 있기 때문에 Rasterization은 실시간 렌더링의 핵심 과정이다.

Pixel / Fragment Processing

각 픽셀이 어떤 색을 가져야 하는지 계산한다.

이 과정에서 Material, Texture, Light, Shadow 등의 정보가 사용된다.


Rendering Path

게임 엔진은 여러 방식으로 장면을 렌더링할 수 있다.

대표적인 방식이 Forward Rendering과 Deferred Rendering이다.

Forward Rendering -> Geometry + Lighting -> Final Image

Forward Rendering은 오브젝트를 렌더링하면서 조명 계산을 수행한다.

구조가 비교적 단순하고 투명한 오브젝트 처리에도 유리하지만, 많은 광원을 사용하는 장면에서는 조명 계산 비용이 커질 수 있다.

Deferred Rendering은 먼저 화면의 여러 정보를 저장한 뒤 조명 계산을 별도로 수행한다.

Geometry -> G-Buffer -> Lighting -> Final Image

G-Buffer에는 일반적으로 위치, Normal, Albedo, Specular 등의 정보가 저장된다.

따라서 많은 광원을 효율적으로 처리하는 데 유리하지만 추가적인 메모리와 대역폭을 사용한다.


Draw Call

CPU가 GPU에게 특정 렌더링 작업을 요청하는 것을 일반적으로 Draw Call이라고 한다.

CPU -> Draw Call -> GPU -> Rendering

오브젝트가 많아지면 Draw Call이 증가할 수 있고, 특히 CPU 측에서 병목이 발생할 수 있다.

그래서 게임 엔진에서는 여러 오브젝트를 묶어서 처리하거나 GPU가 동일한 데이터를 반복해서 사용할 수 있도록 최적화한다.

대표적인 방법이 다음과 같다.

Draw Call Optimization -> Batching / GPU Instancing

Batching

Batching은 여러 렌더링 작업을 하나로 묶어 Draw Call을 줄이는 방법이다.

대표적으로 Static Batching과 Dynamic Batching이 있다.

Multiple Objects -> Batching -> Fewer Draw Calls -> GPU

Unity에서는 오브젝트의 상태와 렌더링 조건에 따라 적절한 Batching 방식을 사용할 수 있다.


GPU Instancing

동일한 Mesh와 Material을 사용하는 오브젝트가 매우 많을 때 GPU Instancing을 사용할 수 있다.

One Mesh + One Material -> Multiple Instances -> GPU

예를 들어 수천 개의 나무나 풀을 렌더링해야 하는 경우 각각을 별도의 Draw Call로 처리하는 것보다 GPU Instancing을 활용하는 것이 효율적이다.


Culling

카메라에 보이지 않는 오브젝트까지 렌더링할 필요는 없다.

따라서 게임 엔진에서는 렌더링 전에 불필요한 오브젝트를 제거한다.

Scene -> Culling -> Visible Objects -> Rendering

대표적인 방법이 Frustum Culling과 Occlusion Culling이다.

Frustum Culling

카메라가 볼 수 있는 영역 밖의 오브젝트를 렌더링 대상에서 제외한다.

Camera Frustum -> Visible Objects -> Rendering

Occlusion Culling

카메라와 오브젝트 사이에 다른 오브젝트가 존재하여 실제로 보이지 않는 오브젝트를 제외한다.

Scene -> Occlusion Test -> Visible Objects -> Rendering

Culling은 렌더링하지 않아도 되는 작업 자체를 제거한다는 점에서 매우 중요한 최적화 방법이다.


LOD

LOD(Level of Detail)는 카메라와의 거리에 따라 모델의 복잡도를 변경하는 기술이다.

Camera -> Near -> High Detail
Camera -> Mid -> Medium Detail
Camera -> Far -> Low Detail

멀리 있는 오브젝트는 화면에서 차지하는 픽셀 수가 작기 때문에 높은 Polygon 수를 사용할 필요가 없다.

따라서 거리에 따라 Mesh의 복잡도를 낮추면 성능을 확보할 수 있다.


Texture와 Mipmap

Texture는 모델의 표면에 적용되는 이미지 데이터다.

Mesh + Texture + Material -> Surface

Texture 해상도가 높을수록 메모리 사용량과 Texture Sampling 비용이 증가할 수 있다.

Mipmap은 하나의 Texture에 여러 단계의 축소된 이미지를 미리 만들어두는 방식이다.

Original Texture -> Mipmap Level 0 / Level 1 / Level 2 / ... -> Appropriate Level Sampling

멀리 있는 오브젝트에는 작은 Mipmap을 사용함으로써 Texture Sampling의 효율을 높이고 화면 품질을 안정적으로 유지할 수 있다.


Lighting

Lighting은 오브젝트가 빛을 어떻게 받는지를 계산하는 과정이다.

Light -> Surface -> Lighting Calculation -> Pixel Color

대표적인 조명 요소로 Directional Light, Point Light, Spot Light 등이 있다.

게임에서는 직접광뿐만 아니라 다른 표면에서 반사된 간접광까지 고려할 수 있다.


Global Illumination

Global Illumination은 빛이 다른 표면에 반사되는 간접광까지 고려하는 개념이다.

Light -> Surface A -> Bounce -> Surface B -> Final Lighting

실시간 GI는 높은 품질을 제공할 수 있지만 연산 비용이 크기 때문에 게임에서는 다양한 최적화 방법을 사용한다.

Lightmap, Light Probe, Reflection Probe 등도 이러한 조명 정보를 효율적으로 처리하기 위한 방법이다.


Shadow

빛이 존재하면 오브젝트에 의해 다른 영역에 그림자가 생긴다.

실시간 그림자의 대표적인 구현 방식이 Shadow Mapping이다.

Light -> Shadow Map -> Camera Rendering -> Shadowed Pixels

Shadow Map은 광원의 시점에서 장면을 렌더링하여 깊이 정보를 저장하고, 실제 카메라 렌더링 과정에서 해당 정보를 비교하여 그림자를 판단한다.

그림자 품질을 높이면 Shadow Map의 해상도나 필터링 비용 등이 증가하기 때문에 성능과 품질 사이의 균형이 필요하다.


Anti-Aliasing

3D 게임에서는 화면의 대각선이나 곡선 부분에서 계단 현상이 발생할 수 있다.

이를 Aliasing이라고 한다.

Continuous Geometry -> Pixel Sampling -> Aliasing

Anti-Aliasing은 이러한 계단 현상을 줄이는 기술이다.

대표적인 방식은 다음과 같다.

Anti-Aliasing -> MSAA / FXAA / SMAA / TAA

MSAA

MSAA는 하나의 픽셀을 여러 샘플로 나누어 Geometry Edge를 더 정확하게 처리한다.

품질이 좋은 편이지만 추가적인 GPU 비용이 발생할 수 있다.

FXAA

FXAA는 완성된 화면을 분석하여 계단 현상이 발생하는 Edge를 후처리 방식으로 부드럽게 만든다.

비용이 저렴하지만 이미지가 흐려질 수 있다.

TAA

TAA는 여러 프레임의 정보를 누적하여 Anti-Aliasing을 수행한다.

Frame N + Frame N-1 + Motion Information -> TAA -> Anti-Aliased Image

현대 게임에서 많이 사용되지만 움직이는 물체에서 Ghosting이나 Blur가 발생할 수 있다.


VSync

GPU가 너무 빠르게 프레임을 생성하면 모니터가 한 프레임을 출력하는 도중 다음 프레임의 일부가 섞일 수 있다.

이를 Tearing이라고 한다.

GPU Frame Output != Display Refresh Timing -> Tearing

VSync는 GPU의 프레임 출력과 디스플레이의 주사율을 동기화하여 이러한 문제를 줄인다.

GPU -> VSync Synchronization -> Display

다만 GPU가 다음 프레임을 준비하지 못하면 화면 출력이 기다리게 되어 Frame Pacing이나 Input Latency에 영향을 줄 수 있다.


Refresh Rate와 FPS

FPS와 Refresh Rate는 비슷해 보이지만 서로 다른 개념이다.

FPS는 GPU와 게임 시스템이 초당 몇 개의 프레임을 생성하는지를 나타내고, Refresh Rate는 디스플레이가 초당 몇 번 화면을 갱신할 수 있는지를 나타낸다.

Game -> FPS -> Frame Generation
Display -> Refresh Rate -> Screen Refresh

예를 들어 60Hz 모니터는 초당 최대 60번 화면을 갱신한다.

따라서 높은 FPS가 항상 화면에 그대로 표시되는 것은 아니다.


VRR

VRR(Variable Refresh Rate)은 디스플레이의 주사율을 고정하지 않고 GPU의 프레임 출력에 맞춰 변경하는 기술이다.

대표적으로 G-Sync와 FreeSync가 있다.

GPU Frame -> VRR -> Display Refresh

VSync가 디스플레이에 맞춰 GPU의 출력을 제어하는 방식이라면 VRR은 디스플레이가 GPU의 프레임 출력에 맞추는 방향으로 이해할 수 있다.


Dynamic Resolution

GPU 부하가 높아져 목표 FPS를 유지하기 어려운 경우 렌더링 해상도를 동적으로 낮출 수 있다.

GPU Load -> Resolution Adjustment -> Rendering -> Target FPS

예를 들어 최종 출력은 1920×1080이지만 내부 렌더링 해상도를 상황에 따라 1600×900, 1280×720 등으로 낮출 수 있다.

낮아진 해상도는 이후 Upscaling을 통해 출력 해상도로 확대한다.


Upscaling

Upscaling은 낮은 해상도로 렌더링한 이미지를 높은 해상도로 확대하는 기술이다.

Low Resolution Rendering -> Upscaling -> Display Resolution

대표적인 기술로 NVIDIA의 DLSS, AMD의 FSR, Intel의 XeSS 등이 있다.

목적은 단순하다.

렌더링해야 하는 픽셀 수를 줄이면서 높은 출력 해상도를 유지하는 것이다.


HDR

HDR(High Dynamic Range)은 더 넓은 밝기와 색 표현 범위를 다루는 기술이다.

일반적인 SDR보다 밝은 영역과 어두운 영역의 표현 범위가 넓다.

HDR Rendering -> Tone Mapping -> Display

HDR 렌더링에서는 매우 밝은 광원이나 어두운 영역을 더 넓은 범위로 표현할 수 있고, 최종적으로 디스플레이가 표현할 수 있는 범위에 맞춰 Tone Mapping을 수행할 수 있다.


Tone Mapping

렌더링 과정에서 계산되는 HDR 색상 값은 일반적인 디스플레이가 그대로 표현할 수 있는 범위를 넘어설 수 있다.

Tone Mapping은 이를 디스플레이가 표현할 수 있는 범위로 변환하는 과정이다.

HDR Color -> Tone Mapping -> Displayable Color -> Display

게임의 전체적인 색감과 밝기에도 큰 영향을 준다.


Post Processing

렌더링이 끝난 이미지를 대상으로 추가적인 화면 처리를 수행할 수 있다.

Rendered Image -> Post Processing -> Final Image

대표적인 효과는 다음과 같다.

Post Processing -> Bloom / Motion Blur / Depth of Field / Color Grading / Vignette / Ambient Occlusion

예를 들어 Bloom은 밝은 영역 주변에 빛이 퍼지는 효과를 추가한다.

Motion Blur는 움직임에 따른 잔상을 표현하고, Depth of Field는 카메라의 초점 거리에 따른 흐림 효과를 표현한다.


Frame Time

게임 성능을 볼 때 FPS만 보는 것보다 Frame Time을 보는 것이 중요하다.

FPS가 초당 생성되는 프레임 수라면 Frame Time은 하나의 프레임을 생성하는 데 걸리는 시간이다.

Frame Time = Frame Processing Time

예를 들어 60 FPS를 유지하려면 한 프레임을 약 16.67ms 이내에 처리해야 한다.

60 FPS -> 16.67ms / Frame
120 FPS -> 8.33ms / Frame
144 FPS -> 6.94ms / Frame

따라서 최적화에서는 단순히 “FPS가 낮다”가 아니라 CPU가 병목인지 GPU가 병목인지, 그리고 어느 작업이 Frame Time을 증가시키는지를 확인해야 한다.


CPU Bound와 GPU Bound

게임은 CPU와 GPU 중 어느 쪽이 더 오래 걸리는지에 따라 병목이 달라진다.

CPU Processing > GPU Processing -> CPU Bound
GPU Processing > CPU Processing -> GPU Bound

CPU Bound라면 Game Logic, Physics, Animation, Draw Call 등의 비용을 확인해야 한다.

GPU Bound라면 Resolution, Shader, Lighting, Shadow, Post Processing 등의 비용을 확인해야 한다.


게임 그래픽스의 전체 흐름

결국 게임 그래픽스는 하나의 거대한 파이프라인으로 볼 수 있다.

Game Logic -> Scene Update -> Culling -> Draw Call -> Rendering Pipeline -> Lighting -> Shadow -> Post Processing -> Anti-Aliasing -> Upscaling -> VSync / VRR -> Display

각 단계는 서로 독립적인 기술처럼 보이지만 실제로는 연결되어 있다.

예를 들어 해상도를 높이면 GPU가 처리해야 하는 Pixel 수가 증가하고, Shadow와 Post Processing의 비용도 증가할 수 있다.

반대로 Culling과 LOD를 적용하면 실제로 처리해야 하는 Geometry와 Rendering 작업을 줄일 수 있다.

게임 그래픽스의 핵심은 결국 제한된 CPU/GPU 자원으로 목표 Frame Time 안에 원하는 품질의 이미지를 만들어내는 것이다.

그래픽 옵션을 이해한다는 것도 결국 이 구조를 이해하는 것이다.

해상도, 그림자 품질, Anti-Aliasing, Texture, LOD, Lighting, Post Processing 등의 옵션은 단순한 “그래픽 품질 설정”이 아니라 GPU 연산량, 메모리 사용량, 대역폭, Frame Time에 직접적인 영향을 주는 렌더링 파라미터다.