본문 바로가기

날씨 효과의 성능 최적화

강수 파티클·볼류메트릭 안개·동적 조명과 시간 갱신 비용을 측정해 날씨 품질과 목표 프레임을 균형 있게 조정합니다.

날씨 효과를 많이 넣을수록 화면은 풍부해지지만, 프레임은 생각보다 빨리 흔들립니다. 특히 강수 파티클과 볼류메트릭 안개, 실시간 조명이 한 장면에서 겹치면 GPU와 CPU 양쪽에서 병목이 생기기 쉽습니다. 그렇다고 효과를 한꺼번에 끄면 앞에서 공들여 만든 분위기도 함께 사라집니다.

이 글에서는 날씨 연출을 최대한 지키면서 목표 프레임을 맞추는 기준을 정리합니다. 강수 파티클, 안개, 구름을 차례로 보며 어떤 설정이 실제 비용을 줄이고 어떤 설정은 보이는 모습만 바꾸는지 구분하고, 시간 시스템과 환경 전체의 최적화, 측정 도구, 비교하는 순서까지 다룹니다. 이 글을 마치면 보기 좋은 효과와 실행할 수 있는 성능 사이의 균형을 스스로 잡을 수 있습니다.


날씨 효과를 최적화해야 하는 이유

날씨 시스템은 많은 파티클과 복잡한 셰이더, 실시간 조명 계산처럼 비용이 큰 요소를 여럿 담고 있어서, 최적화하지 않으면 프레임 속도가 크게 떨어질 수 있습니다. 플레이어가 쾌적하게 게임을 하려면 프레임이 안정적이어야 하고, 날씨가 바뀌는 순간에 프레임이 급락하는 일은 특히 눈에 띕니다.

또 PC뿐 아니라 콘솔과 모바일에서도 게임이 잘 동작하게 하려면 플랫폼마다의 성능 제약을 고려해야 합니다. 끊김 없는 플레이는 몰입을 지키고, 버벅임 같은 부정적인 경험을 줄여 줍니다.


강수 파티클 최적화

비, 눈, 우박 같은 강수 파티클은 한 번에 수천 개의 입자를 그리므로 가장 큰 비용 요인 가운데 하나입니다. 이 비용은 입자를 몇 개 만드느냐, 그중 몇 개를 실제로 그리느냐, 입자 하나를 그리는 데 얼마가 드느냐, 그리고 시뮬레이션을 어느 처리 장치에서 하느냐로 나눠 볼 수 있습니다. 아래 항목은 이 순서를 따르므로, 먼저 입자 수를 줄이고 나서 재질과 시뮬레이션 방식을 손보면 됩니다.

생성 속도와 수명

가장 먼저 볼 것은 동시에 살아 있는 입자의 수입니다. 너무 많은 입자를 한 번에 생성하거나 오래 유지하지 않도록, 나이아가라에서 생성 속도(Spawn Rate)와 한꺼번에 생성하는 버스트(burst)의 수, 입자의 수명(lifetime)을 조절합니다. 계속 일정하게 생성하는 단순한 상태라면, 초당 생성 수에 평균 수명을 곱한 값이 동시에 살아 있는 입자 수의 추정치가 됩니다. 다만 반복 설정이나 입자를 없애는 조건, 컬링에 따라 실제 수는 달라집니다.

계산해 봅니다. 버스트나 중간에 없애는 조건, 컬링이 없고, 초당 300개를 계속 생성하며 수명이 2초라면, 동시에 살아 있는 입자는 약 300 × 2 = 600개입니다. 수명을 1초로 줄이면 약 300개가 되지만, 이때 빗방울이 땅에 닿기 전에 사라지지 않는지도 확인해야 합니다. 또 효과를 막 시작한 직후에는 아직 이 일정한 상태에 이르지 않았으므로 실제 수가 이 값과 다를 수 있습니다.

거리와 가시성으로 걸러 내기

카메라에서 멀어 보이지 않는 파티클은 그리지 않게 합니다. 나이아가라의 이펙트 타입(Effect Type)에서 거리와 가시성에 따른 컬링을 정하고, 시스템마다 덮어쓴(override) 설정이 있는지 확인합니다. 이때 바운드(Bounds)도 함께 봅니다. 바운드는 효과를 감싸는 영역으로, 엔진은 이 영역이 화면 밖에 있으면 효과가 보이지 않는다고 판단합니다. 그래서 바운드가 실제 효과보다 너무 작으면, 화면에 보이는 입자까지 잘못 걸러져 사라질 수 있습니다.

스케일러빌리티로 플랫폼마다 다르게

나이아가라는 이펙트 타입과, 시스템, 이미터, 렌더러 단계의 스케일러빌리티 덮어쓰기로 플랫폼과 품질 단계마다 생성 배율이나 효과를 켤지 여부를 정합니다. 거리에 따라 효과를 바꾸고 싶다면 그에 맞는 연결과 컬링을 따로 구성합니다. 이 기능은 예전 캐스케이드(Cascade) 파티클의 LOD 단계와 같은 기능이 아니므로, 같은 방식으로 생각하지 않습니다. 멀리 있는 파티클에는 더 단순한 재질을 쓰거나, 입자 수를 줄이는 대신 크기를 키워 보이는 품질의 손실을 줄이며 비용을 낮춥니다.

재질과 오버드로

파티클의 재질은 가능한 한 단순하게 만듭니다. 셰이더 명령이 많거나 반투명이 많이 겹치는 재질은 피합니다. 반투명으로 섞는 알파 블렌딩(alpha blending) 대신, 픽셀을 보이거나 안 보이거나 둘 중 하나로 처리하는 마스크드(Masked) 재질로 바꿀 수 있다면 겹침의 비용을 줄일 수 있습니다.

반투명한 파티클이 화면의 같은 픽셀 위에 여러 겹 쌓이면, 그 픽셀을 여러 번 그리는 오버드로(overdraw)가 늘어나 비용이 커집니다. 그래서 입자가 화면에서 차지하는 면적과 겹침, 셰이더 비용을 줄여 비교합니다. 여기서 흔한 오해가 있는데, 알파만 낮춰 거의 투명하게 만든 픽셀도 셰이더 계산은 그대로 합니다. 덜 보인다고 비용이 줄어드는 것은 아닙니다.

CPU 시뮬레이션과 GPU 시뮬레이션

나이아가라 이미터는 입자를 CPU에서 계산할지 GPU에서 계산할지 고를 수 있습니다. GPU 시뮬레이션은 입자가 아주 많은 효과에 알맞을 수 있지만, 목표 GPU에 여유가 있는지와 필요한 기능을 지원하는지 확인해야 합니다. 또 GPU 시뮬레이션이어도 나이아가라 시스템과 이미터 스크립트의 CPU 비용은 남습니다. 앞 글에서 본 충돌 이벤트처럼 CPU 시뮬레이션에서만 되는 기능도 있으므로, 효과에 필요한 기능을 먼저 확인하고 고릅니다.


안개 최적화

안개는 장면의 깊이감을 높이지만, 특히 볼류메트릭 안개는 비용이 큽니다.

먼저 볼류메트릭 계산을 쓰지 않는 일반 지수형 높이 안개만으로 원하는 표현이 되는지 확인합니다. 많은 경우 볼류메트릭 안개 없이 지수형 높이 안개만으로도 충분한 효과를 낼 수 있습니다.

볼류메트릭 안개를 꼭 써야 한다면, 그 설정은 지수형 높이 안개 컴포넌트의 Volumetric Fog 항목에 있습니다. 비용을 정하는 것은 주로 볼류메트릭 안개를 계산하는 3D 격자의 해상도와 범위입니다. 격자의 해상도는 그림자 스케일러빌리티 단계의 영향을 받고, View Distance는 볼류메트릭 안개를 계산할 거리입니다. 광원마다 Cast Volumetric Shadow를 켜면 그 광원이 볼류메트릭 안개에 그림자를 드리우는 비용이 더해집니다.

반면 Albedo와 Extinction Scale, 광원의 Volumetric Scattering Intensity는 주로 안개라는 매질과 빛이 어떻게 보이는지를 바꾸는 값입니다. 계산하는 샘플 수나 거리를 줄이는 품질 옵션과는 다르므로, 이 값을 낮춘다고 비용이 줄 것이라고 기대하지 않습니다. 볼류메트릭 안개는 비용이 크므로, 저사양 플랫폼에서는 쓰는 범위를 제한하거나 완전히 끄는 것을 검토합니다.


구름 최적화

볼류메트릭 클라우드는 매우 사실적이지만 비용도 큽니다. 비용을 줄이는 첫 번째 방법은 샘플 수입니다. VolumetricCloud 액터의 디테일 패널에서 시야 방향의 샘플 배율인 View Sample Count Scale과, 그림자 계산의 샘플 배율인 Shadow View Sample Count Scale을 낮추면 비용이 줄어듭니다.

다음은 구름을 계산하며 따라갈 범위입니다. 구름 컴포넌트의 Tracing Start Max Distance와 Tracing Max Distance 같은 추적 범위를 확인합니다. 이것은 일반 메시를 거리에 따라 그리지 않게 하는 Max Draw Distance 컬링과 같은 동작이 아니므로, 같은 방식으로 생각하지 않습니다. 구름 재질 자체도 복잡한 노이즈 함수나 계산을 줄여 단순하게 만듭니다.

아트 스타일이나 성능 제약에 따라서는 볼류메트릭 클라우드 대신, 하늘 배경에 구름 텍스처를 그리거나 평면 메시에 구름 텍스처를 입히는 예전 방식(billboard)을 쓰는 것도 좋은 선택입니다.


시간 시스템과 환경 전체 최적화

날씨뿐 아니라 시간 시스템과 연결된 환경 전체도 함께 최적화해야 합니다. 시간 시스템은 태양과 하늘, 후처리 값을 매 프레임 조금씩 바꾸므로, 한 번 정해 두고 끝나는 정적인 레벨보다 갱신 비용이 꾸준히 듭니다. 아래에서는 그 영향을 받는 조명, 후처리, 많이 배치한 메시, 레벨 전체에 값을 전하는 재질 파라미터 컬렉션(MPC)을 차례로 점검합니다.

조명

회전하는 디렉셔널 라이트는 Movable이어야 합니다. 나머지 광원은 실행 중에 바뀌는 것과 구운 조명인지 루멘인지에 따라 이동성을 고르고, 그림자를 만드는 광원의 범위와 수를 측정합니다. 포인트 라이트와 스포트 라이트의 Attenuation Radius는 필요한 만큼만 작게 정해, 쓸데없는 그림자와 조명 계산을 줄입니다.

후처리

후처리 볼륨에서 쓰지 않는 효과, 예를 들어 필름 그레인이나 렌즈 플레어는 꺼서 렌더링 비용을 줄입니다. 블룸, 앰비언트 오클루전, 화면 공간 반사처럼 비용이 큰 효과는 품질과 해상도, 켜고 끄는 옵션을 비교합니다. Intensity만 낮춰서는 그 렌더링 단계의 비용이 반드시 줄지 않는다는 점을 기억합니다.

LOD와 컬링

날씨에 반응하는 식물과 바위처럼 많이 배치되는 스태틱 메시에는 알맞은 LOD를 설정해, 멀리서는 폴리곤이 적은 메시가 쓰이게 합니다. 가려서 보이지 않는 오브젝트를 그리지 않는 오클루전 컬링이 제대로 동작하는지 확인하고, 날씨에 영향을 받는 작은 소품에는 컬 디스턴스 볼륨(Cull Distance Volume)을 놓아 일정 거리 밖에서는 그리지 않게 할 수 있습니다.

재질 파라미터 컬렉션

지면의 젖은 정도나 눈 쌓임처럼 레벨 전체에 적용할 값을 MPC로 다루는 것은 효율적입니다. 다만 MPC에 파라미터를 너무 많이 담거나, 값을 지나치게 자주 바꾸지 않도록 주의합니다. 값이 바뀔 필요가 없는 프레임에는 다시 쓰지 않는 편이 좋습니다.


측정 도구 쓰기

최적화는 되풀이하는 과정이므로, 엔진의 성능 분석 도구를 적극적으로 씁니다. Stat FPS는 지금의 프레임 속도를, Stat Unit은 CPU와 GPU의 프레임 시간을 나눠 보여 주어 어느 쪽이 병목인지 알려 줍니다. Stat Engine은 렌더링과 물리처럼 엔진의 여러 시스템에 걸린 시간을 자세히 보여 줍니다.

ProfileGPU는 GPU가 한 프레임을 그리는 동안 각 단계에 걸린 시간을 자세히 보여 주므로, 어느 부분이 GPU를 가장 많이 쓰는지 찾을 수 있습니다. 예를 들어 PostProcess나 Translucency 항목이 높다면, 후처리 효과나 반투명 파티클이 원인 후보입니다.

Light Complexity와 Shader Complexity는 뷰포트의 최적화 뷰 모드(Optimization Viewmodes)에서 고릅니다. 콘솔에서는 viewmode lightcomplexity와 viewmode shadercomplexity 명령을 쓸 수 있는데, 지원 여부는 빌드 구성에 따라 다르므로 확인합니다. 이 색은 실제로 밀리초를 잰 값이 아니라는 점도 기억합니다.


비교하는 순서

날씨 효과의 비용은 다음 순서로 비교합니다. 먼저 같은 카메라와 해상도, 스케일러빌리티에서 CPU와 GPU의 프레임 시간을 기록합니다. 그다음 강수, 안개, 구름 가운데 한 요소만 바꿔 비용의 차이를 비교합니다. 병목으로 확인된 항목은 생성 수나 샘플, 그림자 범위를 줄이고, 그때 시야와 분위기를 얼마나 잃는지도 함께 봅니다. 마지막으로 목표 기기에서 통과한 설정을 플랫폼별 품질 단계로 저장해 둡니다.


정리

  • 강수 파티클은 생성 속도와 수명, 버스트로 동시에 살아 있는 입자 수를 줄이며, 일정한 상태에서는 초당 생성 수 × 수명이 그 추정치입니다.
  • 나이아가라의 이펙트 타입과 스케일러빌리티로 거리와 가시성, 플랫폼에 따라 효과를 줄이고, 바운드가 너무 작으면 보이는 입자도 사라질 수 있습니다.
  • 반투명 파티클의 겹침은 오버드로를 늘리며, 알파만 낮춘 픽셀도 셰이더 비용은 그대로입니다.
  • 안개는 일반 지수형 높이 안개부터 확인하고, 볼류메트릭 안개의 비용은 격자 해상도와 View Distance, 볼류메트릭 그림자가 정하며 Albedo나 Extinction Scale은 모습을 바꾸는 값입니다.
  • 볼류메트릭 클라우드는 샘플 배율과 추적 범위로 비용을 줄이고, 필요하면 텍스처 구름 같은 예전 방식을 씁니다.
  • 후처리는 강도가 아니라 품질과 켜고 끄는 옵션으로 비용을 줄이고, MPC는 파라미터 수와 갱신 빈도를 관리합니다.
  • 같은 조건에서 한 요소씩 바꿔 Stat Unit과 ProfileGPU로 비교하고, 통과한 설정을 플랫폼별 품질 단계로 저장합니다.

연습 문제

1. 입자 수를 400개로 줄이려면

버스트나 컬링이 없고 수명이 2초인 비 효과가 초당 300개를 계속 생성합니다. 수명을 2초로 유지하면서 동시에 살아 있는 입자를 약 400개로 줄이려면 초당 몇 개를 생성해야 할까요? 이렇게 줄이면 프레임 비용도 정확히 1/3 줄어들까요?

해설 보기

동시에 살아 있는 입자 수는 초당 생성 수 × 수명이므로, 400 ÷ 2 = 초당 200개를 생성하면 됩니다. 원래 600개에서 400개로 1/3이 줄어듭니다.

하지만 프레임 비용이 정확히 1/3 줄어든다고 결론 내릴 수는 없습니다. 실제 비용은 입자 수뿐 아니라 입자가 화면에서 차지하는 면적, 재질, 겹침, 시뮬레이션 방식에 따라 달라지기 때문입니다. 바꾼 뒤 같은 조건에서 다시 측정합니다.

2. 거의 투명하게 만들었는데

비 파티클의 비용을 줄이려고 재질의 불투명도를 0.05로 낮춰 거의 보이지 않게 만들었습니다. 그런데 ProfileGPU의 Translucency 시간은 거의 그대로입니다. 왜 그럴까요?

해설 보기

불투명도를 낮춰도 그 픽셀의 셰이더 계산은 그대로 실행되므로, 반투명 입자가 화면에 겹쳐 그려지는 비용은 줄지 않습니다. 덜 보이는 것이 곧 비용이 줄어드는 것은 아닙니다.

비용을 줄이려면 입자의 수나 크기를 줄여 화면에서 차지하는 면적과 겹침을 줄이거나, 재질을 단순하게 하거나, 가능하다면 마스크드 재질로 바꿉니다. 바꾼 뒤 Translucency 시간을 다시 비교합니다.

3. 볼류메트릭 안개의 비용

볼류메트릭 안개가 무거워서 Albedo를 낮추고 Extinction Scale도 줄였는데, GPU 시간은 별로 줄지 않았습니다. 무엇을 바꿔야 실제 비용이 줄어들까요?

해설 보기

Albedo와 Extinction Scale은 안개라는 매질이 어떻게 보이는지를 바꾸는 값이라, 계산하는 양 자체는 거의 그대로입니다.

비용을 줄이려면 볼류메트릭 안개의 계산 범위인 View Distance를 줄이거나, 그림자 스케일러빌리티 단계를 낮춰 격자 해상도를 줄이거나, 광원들의 Cast Volumetric Shadow를 필요한 광원에만 켭니다. 그래도 목표에 못 미친다면 볼류메트릭 안개를 끄고 일반 지수형 높이 안개만으로 표현할 수 있는지 검토합니다.

나이아가라의 스케일러빌리티는 Epic의 나이아가라 스케일러빌리티 안내에서 확인할 수 있습니다.

이것으로 6장을 마칩니다. 6장에서는 안개와 구름, 강수 파티클로 날씨를 만들고 블루프린트로 상태를 바꾸는 방법, 게임 시계 하나로 태양과 조명, 후처리를 함께 움직이는 시간 시스템, 날씨와 시간의 최종 값을 한곳에서 적용하는 구조, 재질 파라미터 컬렉션으로 환경이 함께 반응하게 하는 방법, 그리고 날씨 효과의 비용을 측정하며 줄이는 방법까지 살펴봤습니다. 다음 장의 기본 물리 엔진 설정부터는 물리 엔진의 기본 설정에서 시작해, 중력과 충돌, 물리 재질, 물리 기반 캐릭터 제어, 물리 시뮬레이션의 성능까지 레벨의 물리 환경을 다룹니다.