본문으로 건너뛰기

안동민 개발노트

본문 시작

렌더링 최적화

오버드로우·LOD·그림자·드로우 콜·머티리얼 비용을 진단해 GPU와 렌더 스레드 부하를 낮춥니다.

이전 절에서 우리는 메모리 관리 및 최적화 기법에 대해 살펴보았습니다.

이제 성능 최적화의 또 다른 핵심 영역인 렌더링(Rendering) 최적화에 대해 다뤄보겠습니다.

렌더링은 게임의 시각적 품질을 결정하는 동시에, 가장 많은 CPU와 GPU 자원을 소모하는 부분 중 하나입니다.

프레임 속도(FPS)가 낮거나, 끊김 현상이 발생한다면 대부분의 경우 렌더링 파이프라인에 병목 현상이 발생하고 있을 가능성이 큽니다.

이번 절에서는 언리얼 엔진에서 렌더링 성능을 저하시키는 주요 원인을 이해하고, GPU 및 렌더링 스레드의 부하를 줄여 프레임 속도를 향상시키는 다양한 최적화 기법들을 구체적으로 알아보겠습니다.

렌더링 최적화는 GPU 작업과 렌더 스레드 제출 비용을 먼저 분리한다

화면 품질을 유지하려면 어떤 값을 낮출지보다 어느 비용 축이 프레임을 잡고 있는지부터 확인합니다.

  1. 비용 축 주요 원인 먼저

    줄일 값

  2. 픽셀 복잡도 투명, 마스크드, 텍스처

    샘플, 오버드로우 불투명 우선, 셰이더 명령 수, 파티클 면적

  3. 기하 복잡도 보이

    삼각형 수와 원거리 메시 LOD, HLOD, 모델 단순화, 노멀 맵

  4. 그림자 동적 광원, 캐스케이드, 그림자

    해상도 Cast Shadows 제한, Static/Stationary 우선

  5. 드로우 제출 많

    액터, 머티리얼 전환, 반복 메시 인스턴싱, 머지, 아틀라스, 컬링 설정


렌더링 병목 현상 이해

렌더링 병목 분리와 수정 우선순위

GPU 비용은 오버드로우, 그림자, 후처리, 드로우 콜을 나눠 측정해야 효과적인 최적화 순서를 잡을 수 있습니다.

  1. 1
    프레임 캡처

    문제가 보이는 장면을 고정하고 같은 카메라에서 GPU 비용을 캡처합니다. Baseline

  2. 2
    패스 분석

    BasePass, ShadowDepths, Translucency, PostProcessing 중 큰 항목을 찾습니다. Pass

  3. 3
    원인 매핑

    비싼 패스를 메시, 머티리얼, 라이트, 이펙트 사용처와 연결합니다. Owner

  4. 4
    수정 검증

    한 번에 하나씩 수정하고 프레임 시간 감소를 숫자로 확인합니다. Delta

  5. 5
    프레임 시간

    FPS가 아니라 ms 단위로 개선 폭을 비교합니다.

  6. 6
    화질 손실

    수정 후 게임플레이에 필요한 가독성이 유지되는지 확인합니다.

  7. 7
    장면 대표성

    한 장면 최적화가 다른 주요 장면에 악영향을 주지 않아야 합니다.

이 다이어그램은 렌더링 최적화를 GPU 병목, 드로콜, 머티리얼 비용, LOD 적용 기준으로 나누어 정리합니다.

렌더링 병목은 CPU 제출과 GPU 실행을 나눠 읽는다

프레임이 느릴 때는 드로우콜, 셰이더, 오버드로, 메모리 대역폭을 같은 원인으로 묶지 않고 증상별로 좁힌다.

증상의심 위치확인 도구줄이는 방향
Game/Draw가 높음CPU 렌더 명령 준비Unreal Insights, stat scenerendering동적 객체, Tick, Draw call 정리
GPU가 높음셰이더와 픽셀 처리profilegpu, stat gpu그림자, 후처리, 머티리얼 복잡도 축소
해상도에 민감픽셀 비용·오버드로screen percentage 비교투명 머티리얼, 큰 파티클, 전체 화면 패스 조정
에셋 전환 때 튐텍스처·버퍼 대역폭stat streaming, MemReport텍스처 풀, LOD, 스트리밍 기준 확인
수정 후 그대로병목 축 오판 가능성같은 조건 재측정옵션을 하나씩 바꾸고 이동한 축 기록

렌더링 성능 문제는 크게 GPU 바운드(GPU Bound)CPU 바운드(CPU Bound) (렌더 스레드)로 나눌 수 있습니다.

stat unit 명령을 통해 이 둘 중 어느 쪽에 병목이 있는지 빠르게 파악할 수 있습니다.

  • GPU 바운드: GPU가 렌더링 작업을 처리하는 데 너무 많은 시간이 걸리는 경우입니다.
    • 주요 원인
      • 픽셀 복잡도 (Pixel Complexity): 셰이더 명령 수, 텍스처 샘플링 수, 블렌딩 오버헤드 (오버드로우).
      • 폴리곤 수 (Polygon Count): 화면에 보이는 총 삼각형(Triangles) 수가 너무 많을 때.
      • 해상도: 높은 해상도는 픽셀 수를 증가시켜 GPU 부하를 높입니다.
      • 후처리 효과 (Post-Process Effects): 블룸, DOF, 모션 블러, 안티앨리어싱 등 복잡한 후처리.
      • 그림자: 그림자 맵(Shadow Map) 생성 및 샘플링 비용.
      • 레이 트레이싱: 레이 트레이싱 기능 활성화 시 높은 GPU 자원 소모.
  • CPU 바운드 (렌더 스레드 / RHI 스레드): CPU가 렌더링 명령을 준비하거나 그래픽 API(RHI)로 전송하는 데 너무 많은 시간이 걸리는 경우입니다.
    • 주요 원인
      • 드로우 콜 (Draw Calls): GPU에 보내는 렌더링 명령의 수가 너무 많을 때. 각 드로우 콜은 CPU에 상당한 오버헤드를 유발합니다.
      • 스테이트 변경 (State Changes): 머티리얼, 셰이더, 텍스처 등 렌더링 상태가 자주 변경될 때.
      • 복잡한 씬 그래프: 액터나 컴포넌트의 계층 구조가 너무 복잡하여 렌더링 데이터 준비에 시간이 오래 걸릴 때.
      • 렌더링 데이터 업데이트: 동적인 메시, 텍스처 업데이트 등 CPU가 GPU에 데이터를 보내기 위해 준비하는 과정.

GPU 바운드 최적화 기법

픽셀 복잡도 및 오버드로우 감소

  • 머티리얼 최적화
    • 셰이더 명령어 수 줄이기: 복잡한 수학 연산, 불필요한 텍스처 샘플링을 줄입니다. 머티리얼 에디터의 Stats 탭을 활용하여 셰이더 명령어 수를 확인합니다.
    • 텍스처 압축 및 미드맵(Mipmap): 텍스처를 올바르게 압축하고 미드맵을 사용하여 거리에 따라 낮은 해상도의 텍스처가 사용되도록 합니다.
    • 불투명(Opaque) 머티리얼 우선: 가능한 한 투명(Transparent) 또는 마스크드(Masked) 머티리얼 대신 불투명 머티리얼을 사용합니다. 투명 머티리얼은 오버드로우(Overdraw)를 유발하여 GPU 부하를 크게 증가시킵니다.
    • 블렌딩 모드: 필요한 경우에만 복잡한 블렌딩 모드를 사용하고, 가능한 경우 단순한 모드를 선택합니다.
    • 머티리얼 인스턴스: 동일한 머티리얼을 여러 개 만드는 대신, 머티리얼 인스턴스를 사용하여 파라미터만 변경하고 셰이더 컴파일 비용을 줄입니다.
  • 오버드로우 시각화: Alt + 8을 눌러 Shader Complexity 모드에서 오버드로우를 시각적으로 확인합니다. 붉은색 영역은 GPU 부담이 높은 곳을 나타냅니다.
    • Show -> Visualize -> Buffer Visualization -> Shader Complexity

폴리곤 수 감소 및 LOD 활용

  • LOD (Level Of Detail): 스태틱 메시와 스켈레탈 메시 모두에 LOD를 설정하여 카메라 거리에 따라 자동으로 폴리곤 수가 적은 모델을 사용하도록 합니다. 이는 GPU의 정점 처리 및 픽셀 처리 부하를 줄입니다.
  • 최적화된 모델: 모델링 단계에서 불필요한 폴리곤을 제거하고, 리토폴로지(Retopology)를 통해 메시를 최적화합니다.
  • 노멀 맵 사용: 디테일을 위해 높은 폴리곤을 사용하는 대신, 노멀 맵을 사용하여 저폴리곤 모델에 고품질의 시각적 디테일을 표현합니다.

그림자 최적화

그림자는 렌더링 비용이 매우 높은 기능입니다.

  • 불필요한 그림자 끄기: 작은 오브젝트나 멀리 있는 오브젝트는 그림자를 드리우지 않도록 Cast Shadows 옵션을 끕니다.
  • 그림자 캐스케이드(Cascaded Shadow Maps): Directional Light의 그림자 캐스케이드 수를 줄이거나 거리를 조정하여 비용을 절감합니다.
  • 그림자 해상도: 그림자 맵의 해상도를 적절히 낮춥니다.
  • 캡슐 그림자(Capsule Shadows): 스켈레탈 메시의 경우, 복잡한 그림자 대신 캡슐 그림자를 사용하여 성능을 향상시킬 수 있습니다.
  • 사전 계산된 그림자 (Baked Shadows): 정적인 오브젝트의 그림자는 라이트맵(Lightmap)으로 미리 계산하여 런타임 비용을 줄입니다.

후처리 효과 관리

  • 불필요한 효과 비활성화: 프로젝트 설정에서 사용하지 않는 후처리 효과를 비활성화합니다.
  • 낮은 품질 설정: 후처리 볼륨(Post Process Volume)에서 각 효과의 품질 설정을 조정하여 성능과 시각적 품질 사이의 균형을 맞춥니다.
  • 해상도 스케일: Screen Percentage를 낮춰 렌더링 해상도를 줄이면 GPU 부하를 크게 줄일 수 있습니다. (단, 이미지 품질 저하)

CPU 바운드 (렌더 스레드) 최적화 기법

드로우 콜 감소 (Draw Call Reduction)

드로우 콜은 CPU가 GPU에 렌더링 명령을 보내는 비용이 큰 작업입니다.

드로우 콜 수를 줄이는 것이 중요합니다.

  • 액터 머지(Actor Merging): 여러 개의 스태틱 메시 액터를 하나의 큰 메시로 병합하여 드로우 콜을 줄입니다. (에디터 메뉴: Developer Tools -> Merge Actors)
  • 인스턴싱(Instancing): 동일한 스태틱 메시 컴포넌트나 인스턴싱 스태틱 메시 컴포넌트(UInstancedStaticMeshComponent, UFoliageType)를 사용하여 동일한 메시를 여러 번 렌더링할 때 드로우 콜을 하나로 묶습니다. 나뭇잎, 잔디, 반복되는 건축 요소 등에 매우 효과적입니다.
  • 오브젝트 합체 (LOD 대신): 완전히 동일한 머티리얼을 사용하는 인접한 메시들을 하나의 메시로 합쳐버립니다.
  • 컬링(Culling): 카메라 시야 밖에 있거나 너무 작아서 보이지 않는 오브젝트를 렌더링 파이프라인에서 제외합니다. 언리얼 엔진은 기본적으로 프러스텀 컬링(Frustum Culling)과 오클루전 컬링(Occlusion Culling)을 수행합니다.
    • Hierarchical LOD (HLOD): 대규모 오픈 월드에서 멀리 있는 여러 액터를 하나의 최적화된 메시로 자동 병합하여 드로우 콜과 메시 복잡도를 줄입니다.
    • Manual Occlusion Culling: 커스텀 오클루전 볼륨이나 Precomputed Visibility를 사용하여 수동으로 컬링을 최적화할 수 있습니다.

머티리얼 및 텍스처 변경 최소화

  • 동일한 머티리얼 사용: 인접한 오브젝트에 가능한 한 동일한 머티리얼을 사용하면 렌더링 상태 변경을 줄여 드로우 콜 비용을 절감합니다.
  • 아틀라스 텍스처(Texture Atlases): 여러 작은 텍스처를 하나의 큰 텍스처 시트(아틀라스)에 묶어 사용하여 텍스처 바인딩 비용을 줄입니다.

동적 광원 및 그림자 최적화

동적 광원은 렌더 스레드에 부담을 줍니다.

  • 정적 광원 우선: 가능한 한 많은 광원을 Static 또는 Stationary로 설정하여 라이트맵에 굽고 런타임 비용을 줄입니다.
  • 동적 광원 수 제한: 씬의 동적 광원 수를 최소화합니다.
  • 광원 컴포넌트의 이동성(Mobility): Stationary 광원은 Movable 광원보다 성능이 좋고, Static 광원은 가장 성능이 좋습니다.

기타 렌더링 최적화 팁

  • 엔진 스케일러빌리티 설정: 엔진은 scalability 명령어를 통해 전역적인 그래픽 품질 설정을 제공합니다. r.ScreenPercentage, r.PostProcessAAQuality 등 개별 CVAR(콘솔 변수)을 조절하여 세부적인 렌더링 설정을 변경할 수 있습니다.
  • 플랫폼별 최적화: 모바일, 콘솔, PC 등 타겟 플랫폼의 하드웨어 특성에 맞춰 렌더링 파이프라인을 조절합니다. 예를 들어 모바일에서는 모바일 렌더링 경로를 사용하고, 데스크탑에서는 더 진보된 기능을 활용할 수 있습니다.
  • 리플렉션 캡처 (Reflection Captures): 반사(Reflection)는 성능에 큰 영향을 미칩니다. Reflection Capture 액터를 적절히 배치하고 필요한 경우에만 SSR (Screen Space Reflections)을 사용합니다.
  • 계단 현상(Temporal AA): Temporal AA는 효과적이지만 일부 시나리오에서 고스팅(Ghosting)이나 블러(Blur)를 유발할 수 있습니다. FXAA나 다른 안티앨리어싱 방법을 고려할 수도 있습니다.
  • 개발 빌드 최적화 비활성화: 개발 과정에서는 최적화 기능이 활성화되면 디버깅이 어려울 수 있습니다. 필요할 때만 최적화를 활성화하여 테스트하세요.

렌더링 최적화는 목록을 무작정 적용하기보다, 병목 측정값을 기준으로 GPU와 렌더 스레드 작업을 나누고 작은 변경 단위로 다시 측정하는 루프가 중요합니다.

병목 측정값에서 최적화 순서를 선택한다

`stat unit`, `profilegpu`, Shader Complexity 결과를 먼저 읽고 GPU 작업과 렌더 스레드 작업을 분리하면 불필요한 품질 저하를 줄일 수 있습니다.

  1. GPU ms 높음

    픽셀, 메시, 그림자, 후처리부터 줄입니다.

  2. Draw 높음

    드로우 콜, 스테이트 변경, 컬링을 먼저 봅니다.

  3. GPU Bound
    화면에 그리는 비용이 큰 경우

    GPU Bound 1 투명, 마스크드, 복잡한 머티리얼을 불투명 또는 단순식으로 바꿉니다. 2 멀리 있는 메시와 작은 오브젝트는 낮은 LOD와 제한된 그림자를 사용합니다. 3 Screen Percentage, AA, Bloom은 품질 차이를 직접 보며 줄입니다.

  4. Shader Complexity로 붉은 영역 확인

    투명, 마스크드, 복잡한 머티리얼을 불투명 또는 단순식으로 바꿉니다.

  5. LOD와 그림자 거리 조정

    멀리 있는 메시와 작은 오브젝트는 낮은 LOD와 제한된 그림자를 사용합니다.

  6. 후처리와 해상도 스케일 비교

    Screen Percentage, AA, Bloom은 품질 차이를 직접 보며 줄입니다.

  7. Render Thread Bound
    명령 준비 비용이 큰 경우

    Render Thread Bound 1 foliage, 장식물, 모듈형 구조물은 ISM/HISM 후보로 먼저 분류합니다. 2 같은 머티리얼, 아틀라스, 머티리얼 인스턴스로 전환 비용을 낮춥니다. 3 보이지 않는 액터와 멀리 있는 묶음은 렌더 큐에 들어오기 전에 줄입니다.

  8. 반복 메시를 인스턴싱으로 묶기

    foliage, 장식물, 모듈형 구조물은 ISM/HISM 후보로 먼저 분류합니다.

  9. 머티리얼과 텍스처 상태 변경 축소

    같은 머티리얼, 아틀라스, 머티리얼 인스턴스로 전환 비용을 낮춥니다.

  10. HLOD와 컬링으로 준비 대상 줄이기

    보이지 않는 액터와 멀리 있는 묶음은 렌더 큐에 들어오기 전에 줄입니다.


렌더링 최적화는 복잡하고 지속적인 과정입니다.

GPU와 렌더 스레드의 병목 현상을 정확히 진단하고, 머티리얼, 메시, 그림자, 후처리 효과를 최적화하며, 드로우 콜을 줄이기 위한 인스턴싱 및 컬링 기법을 적용하는 것이 중요합니다.

언리얼 엔진의 profilegpu, stat 명령, Shader Complexity 시각화 모드 등 강력한 프로파일링 도구를 적극적으로 활용하여 렌더링 파이프라인의 병목 현상을 해결하고, 모든 플레이어에게 부드럽고 시각적으로 만족스러운 게임 경험을 제공할 수 있을 것입니다.


렌더링 최적화는 GPU 시간, 드로우 콜, 머티리얼 복잡도, 컬링 상태를 분리해 읽으면 수정 순서가 분명해집니다.

프레임 저하는 GPU와 렌더 스레드 신호를 나눠 읽는다

`profilegpu`, `stat unit`, Shader Complexity 뷰를 함께 보면 픽셀 비용과 렌더 명령 준비 비용을 따로 줄일 수 있습니다.

  1. GPU 시간 확인

    측정 `profilegpu`로 가장 비싼 패스와 후처리 항목을 찾습니다.

  2. 드로우 콜 축소

    Draw 인스턴싱, HLOD, 머티리얼 공유로 렌더 스레드 명령 수를 줄입니다.

  3. 셰이더 단순화

    Shader 복잡한 머티리얼과 오버드로우가 픽셀 비용을 밀어 올리는지 봅니다.

  4. 보이지 않는 것 제거

    Cull 거리 컬링, 오클루전, LOD 설정으로 불필요한 렌더링을 줄입니다.

  5. 신호별 우선 조치

    액터 병합, 인스턴싱, 머티리얼 통합을 먼저 검토합니다. 그림자, 후처리, 투명 효과, 픽셀 셰이더 비용을 낮춥니다. 멀리 있는 메시와 스켈레탈 메시의 폴리곤과 본 비용을 줄입니다.

  6. Draw 높음

    액터 병합, 인스턴싱, 머티리얼 통합을 먼저 검토합니다.

  7. GPU 높음

    그림자, 후처리, 투명 효과, 픽셀 셰이더 비용을 낮춥니다.

  8. LOD 부재

    멀리 있는 메시와 스켈레탈 메시의 폴리곤과 본 비용을 줄입니다.

렌더링 비용은 화면 품질과 성능 목표를 함께 놓고 조정해야 하므로, 어떤 값을 낮출지보다 어떤 경험을 유지할지가 먼저입니다.

렌더링 품질은 기준선을 지키며 한 변수씩 조정한다

같은 장면에서 예산을 재고, 비용 하나만 낮춘 뒤 화면과 프레임 시간을 함께 비교해야 품질 손실의 원인을 추적할 수 있다.

  1. 기준선 고정

    목표 FPS와 반드시 보존할 실루엣·조명·선명도를 정한다.

  2. 병목 측정

    같은 맵과 카메라에서 GPU 캡처로 가장 비싼 구간을 찾는다.

  3. 한 항목 조정

    LOD·그림자·투명 효과 중 원인 하나만 작은 폭으로 낮춘다.

  4. 전후 비교

    프레임 시간의 이득과 화면 차이를 같은 컷에서 나란히 본다.

  5. 기준선 갱신

    품질 허용 범위 안이면 새 값으로 고정하고 다음 병목을 잰다.

  6. 먼 거리부터

    LOD·HLOD·컬링은 플레이어가 덜 느끼는 영역의 비용을 먼저 줄인다.

  7. 반복 요소부터

    식생·소품은 인스턴싱과 배치 밀도 조정의 효과가 크다.

  8. 화면 전체는 마지막

    해상도와 후처리는 영향 범위가 넓어 마지막에 비교한다.

렌더링 최적화에서는 병목 측정, 드로콜 감소, 머티리얼 단순화, LOD 전환 품질을 함께 점검합니다.