icon
9장 : 성능 최적화

자산과 레벨 최적화 기법


이전 절에서 Stat 명령어와 ProfileGPU 같은 언리얼 엔진의 강력한 도구를 사용하여 환경 요소의 성능 병목 현상을 분석하는 방법을 배웠습니다. 이제 이러한 분석 결과를 바탕으로, 게임의 성능을 실제로 향상시킬 수 있는 구체적인 자산(Asset)레벨(Level) 최적화 기법에 대해 알아볼 차례입니다. 모델, 텍스처, 머티리얼, 그리고 레벨 구성 방식 등 다양한 요소들을 효율적으로 관리함으로써, 게임의 시각적 품질을 유지하면서도 안정적인 프레임 속도를 확보할 수 있습니다. '나 혼자 언리얼 기본' 교재를 통해 여러분이 언리얼 엔진에서 자산과 레벨을 최적화하는 다양한 기술을 습득하고, 이를 통해 효율적이고 고성능의 게임을 구축할 수 있도록 안내해 드리겠습니다. 마치 숙련된 건축가가 최소한의 재료로 견고하고 아름다운 건물을 짓듯, 여러분의 게임도 최적화된 자산과 레벨 구성을 통해 최고의 효율을 달성해 봅시다.


자산 및 레벨 최적화의 목표

자산 및 레벨 최적화는 게임의 성능을 좌우하는 핵심 요소입니다.

  • 드로우 콜 (Draw Call) 감소: CPU가 GPU에게 렌더링할 오브젝트를 지시하는 횟수를 줄여 CPU 부하를 경감합니다.
  • 폴리곤 (Polygon) 수 감소: 화면에 그려지는 총 폴리곤 수를 줄여 GPU 부하를 경감합니다.
  • 텍스처 메모리 사용량 감소: 텍스처가 차지하는 VRAM(비디오 램) 사용량을 줄여 GPU 메모리 병목을 해소합니다.
  • 오버드로우 (Overdraw) 감소: 투명하거나 반투명한 부분이 겹쳐 그려지는 횟수를 줄여 GPU 부하를 경감합니다.
  • 섀도우 맵 (Shadow Map) 메모리/연산 감소: 그림자 관련 연산 및 메모리 사용량을 줄입니다.
  • 데이터 크기 감소: 게임의 빌드(Binary) 크기와 런타임 메모리 사용량을 줄입니다.

메시 (Mesh) 최적화

가장 기본적이면서도 중요한 최적화 대상은 3D 모델, 즉 메시입니다.

폴리곤 수 감소 (Poly Count Reduction)

  • 필요성: 화면에 보이는 총 폴리곤 수가 많을수록 GPU 렌더링 부하가 커집니다.
  • 방법
    • 리토폴로지 (Retopology): 외부 3D 모델링 툴(Blender, Maya, ZBrush 등)에서 모델의 폴리곤 밀도를 최적화합니다.
    • 디시메이션 (Decimation): 언리얼 엔진 내에서 Static Mesh Editor메시 Simplification (Mesh Simplification) 도구를 사용하여 폴리곤 수를 줄일 수 있습니다. (프로세스 탭)
      • 주의: 너무 줄이면 디테일 손실이 크거나 외형이 깨질 수 있으므로, 육안으로 확인하며 적절한 수준을 찾아야 합니다.
    • 불필요한 디테일 제거: 플레이어에게 보이지 않는 면(벽 뒤, 땅 속)의 폴리곤은 과감히 제거합니다.

LOD (Level of Detail)

  • 필요성: 멀리 있는 오브젝트는 가까이 있는 오브젝트만큼 디테일할 필요가 없습니다. LOD는 거리에 따라 메시의 폴리곤 수를 자동으로 줄여 GPU 부하를 경감합니다.
  • 설정

    Static Mesh Editor를 엽니다.

    Details 패널의 LOD Settings 섹션에서 Num LODs를 설정합니다. (기본적으로 1)

    LOD Import 섹션에서 외부에서 가져온 LOD 메시를 할당하거나, Generate LODs를 클릭하여 엔진이 자동으로 LOD를 생성하도록 합니다.

    각 LOD의 Screen Size를 조절하여 어떤 거리에서 해당 LOD가 활성화될지 정의합니다.

    LOD Coloration 뷰 모드 (뷰 모드 > LOD 색상)를 사용하여 각 LOD가 언제 활성화되는지 시각적으로 확인합니다.

  • : 수동으로 만든 LOD가 자동 생성된 LOD보다 품질이 좋고 효율적일 수 있습니다.

충돌 메시 최적화

  • 필요성: 물리 시뮬레이션의 성능에 가장 직접적인 영향을 미 미칩니다.
  • 방법: 7장 5절 "물리 시뮬레이션 성능 조정"에서 다룬 것처럼, Simple Collision (단순 충돌) 을 적극적으로 사용합니다.
    • Static Mesh Editor에서 Collision 메뉴를 통해 Add Box/Sphere/Capsule Simplified Collision 또는 Auto Convex Collision을 사용하여 단순 충돌을 생성합니다.
  • Complex Collision (복잡 충돌)은 극도로 제한적으로 사용합니다. (예: Collision ComplexityUse Complex as Simple로 설정하는 것)

텍스처 (Texture) 최적화

텍스처는 VRAM 사용량에 큰 영향을 미칩니다.

해상도 조정 (Resolution Adjustment)

  • 필요성: 텍스처 해상도가 높을수록 더 많은 VRAM을 소모합니다.
  • 방법
    • 텍스처 에셋 더블클릭: Details 패널의 Compression SettingsMax Texture Size를 조정합니다.
    • Max Texture Size: 텍스처의 최대 해상도를 제한합니다. (예: 2048x2048 대신 1024x1024)
    • Power of 2 (2의 거듭제곱): 텍스처 해상도는 2의 거듭제곱(예: 256, 512, 1024, 2048)으로 설정하는 것이 GPU 효율에 좋습니다.
  • 활용: 멀리 있거나 중요하지 않은 오브젝트의 텍스처는 낮은 해상도를 사용합니다.

압축 설정 (Compression Settings)

  • 필요성: 적절한 압축 설정을 통해 텍스처 파일 크기와 VRAM 사용량을 줄일 수 있습니다.
  • 방법: 텍스처 에셋의 Details 패널에서 Compression Settings를 선택합니다.
    • Default (DXT1/5): 일반적인 컬러 텍스처에 사용됩니다. (RGBA 채널에 따라 자동 선택)
    • Normalmap: 노멀 맵에 사용됩니다.
    • VectorDisplacementmap: 변위 맵에 사용됩니다.
    • UserInterface2D (RGBA): UI 텍스처 등 알파 채널이 중요한 경우.
    • Masks (R, G, B, A): 채널별로 독립적인 데이터를 담는 마스크 텍스처에 사용됩니다. (예: AO, Roughness, Metallic을 하나의 텍스처에 묶을 때)
  • : 불필요한 알파 채널을 제거하거나, 여러 흑백 맵(AO, Roughness, Metallic)을 하나의 텍스처의 각 채널에 넣어 VRAM 사용량을 절약하는 것이 좋습니다.

밉맵 (Mipmap)

  • 필요성: 밉맵은 텍스처의 여러 해상도 버전을 미리 생성하여, 오브젝트가 멀리 있을수록 낮은 해상도의 텍스처를 사용하게 합니다. 이는 렌더링 성능과 텍스처 캐시 효율을 높입니다.
  • 설정: 대부분의 텍스처는 기본적으로 밉맵이 활성화되어 있습니다. 텍스처 에셋의 Details 패널에서 Mip Gen Settings를 확인합니다. (UI 텍스처처럼 밉맵이 불필요한 경우 NoMipmaps로 설정)

머티리얼 (Material) 최적화

복잡한 머티리얼은 셰이더 연산 부하를 증가시킵니다.

셰이더 복잡도 감소

  • 필요성: 머티리얼 그래프의 노드 수가 많거나, 고비용 연산(삼각 함수, 복잡한 텍스처 샘플링, 조건부 분기)이 많을수록 GPU 셰이더 연산 부하가 커집니다.
  • 방법
    • Shader Complexity 뷰 모드: 가장 비싼 머티리얼을 식별합니다.
    • 최적화
      • 불필요한 노드 제거.
      • 연산량이 많은 노드 대신 간단한 수학 연산 사용.
      • Static Switch Parameter를 사용하여 사용하지 않는 브랜치를 컴파일 시 제거.
      • 여러 머티리얼에 걸쳐 중복되는 로직은 머티리얼 함수 (Material Function) 로 만들어 재사용.
      • 마스터 머티리얼 - 인스턴스 (Master Material - Instance) 패턴을 사용하여 머티리얼 인스턴스에서 파라미터만 변경하여 재컴파일 시간을 줄입니다.
  • : Lit 머티리얼보다 Unlit 머티리얼이 훨씬 성능 효율적입니다. 배경 오브젝트나 UI에 활용을 고려합니다.

오버드로우 감소 (Overdraw Reduction)

  • 필요성: 투명/반투명 머티리얼(유리, 물, 파티클, 식물 잎)은 겹쳐질수록 여러 번 렌더링되어 GPU 부하를 크게 증가시킵니다.
  • 방법
    • Overdraw 뷰 모드: 오버드로우가 심한 부분을 식별합니다.
    • Masked 머티리얼 사용: 투명도 대신 마스크(Alpha Test)를 사용하는 Masked 블렌드 모드는 오버드로우가 훨씬 적습니다. (예: 나뭇잎, 울타리, 풀)
    • 투명 오브젝트 수 제한: 한 화면에 보이는 투명 오브젝트의 수를 줄입니다.
    • 파티클 최적화: 파티클 시스템에서 파티클의 수, 크기, 수명, 텍스처 오버드로우를 최소화합니다.

레벨 (Level) 최적화

레벨 구성 방식도 성능에 큰 영향을 미칩니다.

액터 병합 (Merge Actors)

  • 필요성: 여러 작은 스태틱 메시 액터들을 하나의 큰 메시로 병합하여 드로우 콜을 크게 줄이고 렌더링 효율을 높입니다.
  • 사용법: 레벨 에디터에서 병합할 액터들을 모두 선택한 후, 창(Window) > 개발자 도구(Developer Tools) > 액터 병합(Merge Actors)를 클릭합니다.
  • 활용: 건축물 구성 요소(벽, 창문, 기둥)나 작은 오브젝트 그룹(돌 무더기, 나뭇가지 묶음)에 효과적입니다.
  • 주의: 병합된 액터는 더 이상 개별적으로 움직이거나 LOD를 가질 수 없게 됩니다. 동적인 오브젝트에는 적합하지 않습니다.

컬링 (Culling)

  • 필요성: 화면에 보이지 않는 오브젝트는 렌더링되지 않도록 하여 성능을 절약합니다.
  • 종류
    • 프러스텀 컬링 (Frustum Culling): 카메라 시야(Frustum) 밖에 있는 오브젝트는 렌더링되지 않습니다. (엔진이 자동으로 수행)
    • 오클루전 컬링 (Occlusion Culling): 다른 오브젝트에 완전히 가려져 보이지 않는 오브젝트는 렌더링되지 않습니다. (엔진이 자동으로 수행)
    • 거리 컬링 (Distance Culling): 특정 거리 밖에 있는 오브젝트는 아예 렌더링되지 않도록 설정합니다.
      • 설정: Static Mesh ComponentDetails 패널에서 Rendering 섹션의 Cull DistanceMin Cull DistanceMax Cull Distance를 설정합니다. (작은 오브젝트에 매우 유용)
    • LOD 기반 컬링: LOD 중 가장 낮은 LOD(예: LOD 3)에 Screen Size0으로 설정하면, 해당 LOD가 활성화되는 거리에서 오브젝트가 완전히 컬링됩니다.

스태틱 라이팅 (Static Lighting) 적극 활용

  • 필요성: 동적 광원(Dynamic Lights)은 런타임에 실시간으로 그림자를 계산하므로 성능 부하가 큽니다.
  • 방법: 6장 1절에서 다룬 것처럼, 대부분의 환경 광원(Directional Light, Sky Light, Point Light, Spot Light)은 MobilityStatic 또는 Stationary 로 설정하여 라이트맵(Lightmap)에 구워 성능을 최적화합니다.
  • Movable 광원: 반드시 실시간 그림자나 변화가 필요한 경우에만 사용하고, 그 수를 최소화합니다.

프로파일링 및 반복

  • 가장 중요한 과정: 최적화는 한 번에 끝나는 것이 아니라, 분석 -> 적용 -> 재측정 -> 재분석의 반복적인 과정입니다.
  • 단계적 접근: 한 번에 너무 많은 것을 최적화하려 하지 말고, Stat Unit이나 ProfileGPU를 통해 가장 큰 병목부터 해결해 나갑니다.

자산과 레벨 최적화는 게임의 성능을 결정짓는 핵심적인 요소입니다. 이 절에서 배운 메시, 텍스처, 머티리얼 최적화 기법과 레벨 최적화 전략들을 바탕으로, 여러분의 게임을 더욱 효율적이고 안정적으로 만들어 나가세요. 끊임없는 분석과 개선을 통해 플레이어에게 최상의 게임 경험을 제공할 수 있을 것입니다.