icon
9장 : 성능 최적화

환경 요소의 성능 분석


이전 장들에서 레벨의 시각적, 물리적, 상호작용적 요소들을 다채롭게 구현하는 방법을 배웠습니다. 이제 여러분의 레벨은 매우 풍부하고 생동감 있게 느껴질 것입니다. 하지만 이러한 복잡하고 상세한 게임 세계는 필연적으로 컴퓨터 성능에 큰 부담을 줍니다. 게임 개발에서 성능 최적화(Performance Optimization) 는 단순히 게임을 '빨리' 돌리는 것을 넘어, 모든 플레이어의 기기에서 원활하고 안정적인 프레임 속도를 유지하며, 최적의 사용자 경험을 제공하기 위한 필수적인 과정입니다. '나 혼자 언리얼 기본' 교재를 통해 여러분이 언리얼 엔진에서 환경 요소들의 성능 병목 현상을 식별하고, 이를 분석하여 효율적인 최적화 방안을 모색하는 방법을 안내해 드리겠습니다. 마치 복잡한 기계의 효율성을 분석하듯, 여러분의 레벨을 구성하는 각 환경 요소가 시스템 자원을 얼마나 소모하는지 정확히 파악해 봅시다.


성능 최적화의 중요성 및 목표

성능 최적화는 게임 개발의 전 과정에 걸쳐 지속적으로 이루어져야 하는 작업입니다.

  • 프레임 속도 (FPS) 유지: 플레이어가 쾌적하게 게임을 즐기려면 안정적인 프레임 속도(초당 프레임 수)가 필수적입니다. 목표 FPS (예: PC 60 FPS, 모바일 30 FPS)를 달성하고 유지해야 합니다.
  • 다양한 하드웨어 지원: 저사양 기기에서도 게임이 원활하게 작동하도록 하여 더 많은 플레이어에게 접근성을 제공합니다.
  • 배터리 효율 (모바일): 모바일 게임의 경우, 최적화는 배터리 소모를 줄여 플레이 시간을 늘리는 데 기여합니다.
  • 개발 효율성: 최적화된 프로젝트는 빌드 시간 단축, 에디터 성능 향상 등 개발 과정 자체의 효율성도 높입니다.
  • 버그 감소: 성능 저하로 인한 물리 버그, 로딩 지연 등의 문제를 예방합니다.

성능 분석을 위한 기본 개념

성능 분석을 시작하기 전에 몇 가지 핵심 개념을 이해해야 합니다.

CPU (Central Processing Unit)

  • 역할: 게임 로직, 물리 시뮬레이션, AI 계산, 애니메이션 블렌딩, 드로우 콜(Draw Call) 준비 등 게임의 '두뇌' 역할을 하는 모든 계산을 담당합니다.
  • CPU 바운드 (CPU Bound): CPU가 GPU보다 느려 게임의 전체 프레임 속도를 제한하는 상태를 의미합니다.
  • 주요 병목 요인
    • 과도한 블루프린트/C++ 로직: Event Tick에서 너무 복잡한 계산을 수행.
    • 많은 액터 수: 레벨에 배치된 액터 수가 너무 많거나, 복잡한 로직을 가진 액터가 많을 때.
    • 물리 시뮬레이션: 동시에 많은 오브젝트가 물리 시뮬레이션될 때.
    • AI 계산: 복잡한 AI 로직이나 많은 수의 AI 캐릭터.
    • 드로우 콜: CPU가 GPU에게 렌더링할 오브젝트 목록을 전달하는 횟수. 드로우 콜 수가 많으면 CPU 오버헤드가 증가합니다.

GPU (Graphics Processing Unit)

  • 역할: 메시 렌더링, 셰이더 계산, 포스트 프로세싱, 그림자, 광원 계산 등 그래픽 관련 모든 작업을 담당합니다.
  • GPU 바운드 (GPU Bound): GPU가 CPU보다 느려 게임의 전체 프레임 속도를 제한하는 상태를 의미합니다.
  • 주요 병목 요인
    • 폴리곤 수: 화면에 보이는 총 폴리곤 수가 너무 많을 때.
    • 오버드로우 (Overdraw): 투명하거나 반투명한 오브젝트(파티클, 유리, 식물)가 많이 겹쳐 렌더링될 때.
    • 복잡한 셰이더/머티리얼: 연산량이 많은 복잡한 머티리얼 사용.
    • 그림자: 다수의 동적 그림자 또는 고해상도 그림자.
    • 포스트 프로세싱: 블룸, 앰비언트 오클루전, 스크린 스페이스 리플렉션 등 고비용 후처리 효과.
    • 광원: 동적 광원 수가 많거나, 넓은 범위에 영향을 미치는 광원.

언리얼 엔진의 성능 분석 도구

언리얼 엔진은 CPU와 GPU 병목 현상을 진단할 수 있는 다양한 도구를 제공합니다.

Stat 명령어

게임 플레이 중 (Alt + P 또는 Play 버튼) 콘솔 (Shift + ~ 키)에 입력하여 실시간 통계를 확인할 수 있습니다.

  • Stat FPS: 현재 프레임 속도(FPS)를 표시합니다. 가장 기본적인 성능 지표입니다.
  • Stat Unit
    • Game: CPU에서 게임 로직(블루프린트, AI, 물리) 처리 시간 (밀리초).
    • Draw: CPU에서 렌더링 명령을 GPU에 전달하는 시간 (드로우 콜 준비).
    • GPU: GPU에서 그래픽 렌더링 시간 (밀리초).
    • Frame: 총 프레임 시간 (밀리초).
    • 활용: Game 시간이 높으면 CPU 바운드, GPU 시간이 높으면 GPU 바운드를 의심할 수 있습니다. Draw 시간이 높다면 CPU가 드로우 콜 준비에 너무 많은 시간을 쓰고 있다는 의미입니다.
  • Stat Engine: 엔진의 다양한 서브시스템(렌더링, 물리, 애니메이션 등)의 CPU 시간을 상세하게 보여줍니다. Game 시간이 높을 때 어느 부분이 문제인지 더 깊이 파고들 때 사용합니다.
  • Stat SceneRendering: 렌더링 파이프라인의 각 단계에 대한 GPU 시간을 상세하게 보여줍니다. GPU 시간이 높을 때 어느 렌더링 단계가 문제인지 파악하는 데 유용합니다. (예: Lights, Translucency, PostProcess)
  • Stat RHI: 하위 수준 렌더링 인터페이스 통계를 보여줍니다.
  • Stat D3D12RHI / Stat VulkanRHI: 특정 그래픽 API에 대한 상세 통계를 보여줍니다.

ProfileGPU

  • 역할: GPU 렌더링 파이프라인의 각 단계에서 정확히 얼마의 시간이 소요되는지 계층적으로 보여주는 강력한 도구입니다.
  • 사용법: 게임 플레이 중 콘솔에 ProfileGPU 를 입력합니다. 별도의 창이 뜨면서 상세한 GPU 통계가 표시됩니다.
  • 활용: Translucency (투명도, 파티클), PostProcess (후처리), ShadowDepths (그림자 깊이), BasePass (주요 메시 렌더링) 등 어느 렌더링 단계가 가장 많은 시간을 소모하는지 파악하여 GPU 병목의 근본 원인을 찾습니다.

뷰포트 시각화 모드

레벨 에디터 뷰포트 좌측 상단의 뷰 모드(View Mode) 드롭다운 메뉴에서 선택할 수 있습니다.

  • Overdraw (오버드로우): 투명/반투명 오브젝트가 겹쳐 렌더링되는 정도를 색상으로 보여줍니다. 흰색에 가까울수록 오버드로우가 심하여 GPU 부하가 높습니다. (예: 많은 파티클, 복잡한 식물)
  • Shader Complexity (셰이더 복잡도): 머티리얼의 셰이더 연산 복잡도를 색상으로 보여줍니다. 빨간색에 가까울수록 셰이더가 복잡하여 GPU 부하가 높습니다.
  • Light Complexity (광원 복잡도): 각 픽셀에 영향을 미치는 광원의 수를 색상으로 보여줍니다. 동적 광원이 많은 영역을 식별합니다.
  • Collision (충돌): 오브젝트의 충돌 메시를 시각적으로 보여줍니다. 불필요하게 복잡한 Complex Collision을 찾아낼 수 있습니다.
  • LOD Coloration (LOD 색상): 각 메시의 현재 LOD 레벨을 색상으로 보여줍니다. LOD가 적절하게 작동하는지, 너무 낮은 LOD가 사용되거나 너무 높은 LOD가 멀리서 사용되는지 확인합니다.
  • 활용: 시각적으로 병목 현상이 예상되는 부분을 빠르게 식별할 수 있습니다.

환경 요소별 성능 분석 포인트

이제 실제 환경 요소들을 위 도구들을 사용하여 어떻게 분석하는지 알아봅시다.

메시 (Meshes)

  • Stat SceneRendering & Stat D3D12RHI: BasePass, DrawCalls 항목을 확인하여 화면에 보이는 메시의 총 폴리곤 수, 드로우 콜 수를 확인합니다.
  • LOD Coloration 뷰 모드: 메시 LOD가 적절하게 작동하는지 확인합니다. 너무 멀리 있는 오브젝트가 높은 LOD로 렌더링되고 있지 않은지 확인합니다.
  • 해결책
    • 불필요한 메시 폴리곤 감소 (리토폴로지, 최적화).
    • 적절한 LOD 설정 및 생성.
    • 하나의 메시로 합칠 수 있는 인접한 작은 메시들을 액터 병합 (Merge Actors) 기능으로 합쳐 드로우 콜 감소.

머티리얼 및 셰이더 (Materials & Shaders)

  • Shader Complexity 뷰 모드: 복잡한 셰이더를 사용한 오브젝트를 식별합니다.
  • ProfileGPU: BasePass 항목 내의 Shader 관련 비용을 확인합니다.
  • 해결책
    • 복잡한 셰이더 연산 (특히 픽셀 셰이더) 최소화.
    • 텍스처 샘플러 수 줄이기.
    • 불필요한 노드 제거.
    • Translucent (투명) 머티리얼 사용 최소화 (오버드로우 유발).

광원 (Lighting)

  • Light Complexity 뷰 모드: 동적 광원이 너무 많은 영역을 식별합니다.
  • Stat SceneRendering & ProfileGPU: Lights, ShadowDepths 항목을 확인하여 광원 계산 및 그림자 렌더링 비용을 분석합니다.
  • 해결책
    • 가능한 Static 또는 Stationary 광원을 사용하고 Movable 광원 수는 최소화.
    • 광원의 Attenuation Radius를 필요한 만큼만 작게 설정.
    • 그림자 품질 설정 조정.

파티클 및 특수 효과 (Particles & VFX)

  • Overdraw 뷰 모드: 투명 파티클의 오버드로우 정도를 확인합니다.
  • Stat SceneRendering & ProfileGPU: Translucency 항목을 확인하여 투명 오브젝트 렌더링 비용을 분석합니다.
  • 해결책
    • 파티클 스폰 속도 및 최대 파티클 수 제한.
    • 파티클 재질의 오버드로우 최소화 (Masked 재질 고려).
    • 파티클의 Cull Distance 설정.
    • GPU 파티클 시스템 (Niagara의 GPU Compute Sim) 고려.

물리 시뮬레이션 (Physics Simulation)

  • Stat Physics: 물리 오브젝트 수, 충돌 쌍 수, 물리 스텝 시간 등을 확인하여 CPU 병목을 진단합니다.
  • Collision 뷰 모드: 불필요하게 복잡한 충돌 메시를 식별합니다.
  • 해결책
    • Simple Collision 적극 활용, Complex Collision 사용 제한.
    • Simulate Physics 활성화 오브젝트 수 제한.
    • 물리 오브젝트 '슬립' 활용.
    • 고속 오브젝트에만 CCD 사용.

포스트 프로세싱 (Post Processing)

  • ProfileGPU: PostProcess 항목을 확인하여 후처리 효과의 비용을 분석합니다.
  • 해결책
    • 불필요한 후처리 효과 비활성화.
    • 각 효과의 품질(Intensity, Quality, Resolution 등) 설정 조정.

성능 분석 및 최적화 워크플로우

목표 설정: 프로젝트의 목표 플랫폼과 목표 FPS를 명확히 합니다.

측정 및 분석

  • 문제가 발생할 것으로 예상되는 영역(가장 복잡한 레벨, 오브젝트가 많은 곳)에서 테스트를 진행합니다.
  • Stat Unit, ProfileGPU, 뷰포트 시각화 모드 등 도구를 사용하여 병목 현상을 식별합니다.
  • CPU 바운드인지, GPU 바운드인지 먼저 파악합니다.

원인 식별: 분석된 데이터를 바탕으로 병목의 구체적인 원인(예: 과도한 오버드로우, 복잡한 셰이더, 너무 많은 물리 오브젝트)을 식별합니다.

최적화 적용: 식별된 원인에 맞춰 이 절에서 제시된 최적화 전략들을 적용합니다.

재측정 및 반복: 최적화를 적용한 후 다시 성능을 측정하여 개선 여부를 확인합니다. 만족할 만한 결과가 나올 때까지 이 과정을 반복합니다.


환경 요소의 성능 분석은 여러분의 게임을 더욱 전문적이고 안정적으로 만드는 데 필수적인 과정입니다. 이 절에서 배운 성능 관련 기본 개념, 언리얼 엔진의 강력한 분석 도구(Stat 명령어, ProfileGPU, 뷰포트 시각화), 그리고 각 환경 요소별 분석 포인트를 바탕으로 여러분의 레벨을 체계적으로 진단하고 개선해 보세요. 꾸준한 분석과 최적화만이 플레이어에게 최고의 경험을 선사할 수 있습니다.