본문으로 건너뛰기

안동민 개발노트

본문 시작

스크립트 최적화 기본 기법

불필요한 매 프레임 계산과 정밀도를 줄이고 CPU·GPU 실행, LOD·스케일러빌리티, 프로파일링으로 스크립트 비용을 관리합니다.

나이아가라는 매우 강력하고 유연한 파티클 시스템이지만, 그만큼 비효율적으로 사용될 경우 성능에 큰 부담을 줄 수 있습니다.

특히 복잡한 효과를 만들거나 많은 파티클을 사용할 때는 스크립트 최적화(Script Optimization)가 필수적입니다.

최적화는 단순히 빠르게 만드는 것을 넘어, 여러분의 효과가 다양한 하드웨어에서 안정적으로 작동하고 게임의 전체적인 프레임 레이트(Frame Rate)를 저하시키지 않도록 보장하는 중요한 과정입니다.

이 절에서는 나이아가라 스크립트의 성능을 향상시키기 위한 몇 가지 기본적인 최적화 기법에 대해 알아보겠습니다.

스크립트 최적화 기본 기법

나이아가라 스크립트 최적화는 파티클 수, 업데이트 단계, 네임스페이스 덮어쓰기, CPU/GPU 실행 위치를 나눠 불필요한 계산을 줄이는 작업입니다.

  1. 1
    Emitter·Particle 단계 비용 줄이기

    Particle Update 시간, 활성 파티클 수, 모듈별 비용을 같은 장면에서 기록합니다. 2 사용하지 않는 모듈과 카메라 밖 업데이트를 끄고 Cull Distance로 총 실행량을 줄입니다. 3 모든 파티클에 같은 계산은 Emitter·System 단계로 옮기고 고정 값은 캐시합니다. 4 이벤트·읽기백이 필요하면 CPU, 대량 독립 계산은 GPU 후보로 두고 같은 조건에서 다시 잽니다.

  2. 2
    비용 기준선 측정

    Particle Update 시간, 활성 파티클 수, 모듈별 비용을 같은 장면에서 기록합니다.

  3. 3
    실행하지 않을 일 제거

    사용하지 않는 모듈과 카메라 밖 업데이트를 끄고 Cull Distance로 총 실행량을 줄입니다.

  4. 4
    반복 계산 끌어올리기

    모든 파티클에 같은 계산은 Emitter·System 단계로 옮기고 고정 값은 캐시합니다.

  5. 5
    실행 위치 선택·재측정

    벤트·읽기백이 필요하면 CPU, 대량 독립 계산은 GPU 후보로 두고 같은 조건에서 다시 잽니다.

  6. 6
    Niagara 스크립트 비용 예산

    스크립트 최적화는 Particle Update 시간, 활성 파티클 수, 모듈별 비용을 함께 줄여야 효과가 납니다. 반복 연산은 Particle Update보다 Emitter나 System 단계로 올리고, 프레임마다 변하지 않는 값은 캐시합니다. 동시에 활성화되는 파티클이 많을수록 Spawn Rate, Lifetime, Cull Distance를 함께 낮춰 총 업데이트 수를 제한합니다.


왜 최적화해야 할까요?

나이아가라 최적화는 파티클 수와 계산 비용을 함께 본다

파티클 수만 줄이면 원인을 놓칠 수 있으므로 모듈 계산, CPU/GPU 실행 위치, LOD, 오버드로우를 분리한다.

비용 축먼저 보는 지표낮출 설정확인 도구
Count동시 파티클 수와 생성량Spawn Rate, Burst Count, LifetimeNiagara Debugger, stat Niagara
Module Cost수학, 조건, DI 호출 빈도불필요한 모듈, 반복 호출 제거Module timing, Insights
Sim TargetCPU/GPU 중 병목 위치GPU 전환 또는 CPU 이벤트 축소stat unit, profiler
Overdraw큰 반투명 입자 겹침크기, 알파, 머티리얼 복잡도Shader Complexity, profilegpu
Scalability거리와 플랫폼별 품질LOD, Cull Distance, Quality Level같은 장면 재측정

나이아가라 시스템은 매 프레임마다 수천, 수만 개의 파티클에 대한 수백 가지의 계산을 수행할 수 있습니다.

각 계산이 아무리 사소해 보여도, 이들이 쌓이면 엄청난 연산량이 됩니다.

특히 다음과 같은 경우에 최적화의 필요성이 더욱 커집니다.

  • 많은 파티클 수: 동시에 활성화되는 파티클 수가 많을수록 각 파티클에 대한 연산 부담이 커집니다.
  • 복잡한 모듈 로직: 복잡한 수학 연산, 조건문, 데이터 인터페이스 호출 등이 많을수록 연산 시간이 늘어납니다.
  • 성능 민감한 플랫폼: 모바일 기기, VR 등 사양이 제한적인 플랫폼에서는 작은 최적화로도 큰 성능 향상을 기대할 수 있습니다.
  • 다수의 이펙트 동시 재생: 여러 나이아가라 효과가 한 화면에 동시에 재생될 때, 각각의 최적화가 전체 성능에 영향을 미칩니다.

불필요한 계산 피하기

가장 기본적인 최적화는 불필요한 일을 하지 않는 것입니다.

  • 사용하지 않는 모듈 제거: 이미터에 추가되어 있지만 실제로는 아무런 기능도 하지 않거나, 더 이상 필요 없는 모듈은 과감하게 삭제하세요. 각 모듈은 나름의 연산 비용을 가집니다.
  • 조건문을 활용한 계산 제한: 특정 조건에서만 실행되어야 하는 복잡한 계산이 있다면, If 노드를 사용하여 해당 조건이 만족될 때만 계산이 수행되도록 합니다.
    • 예시: 파티클이 땅에 닿았을 때만 마찰력을 계산한다면, OnGround와 같은 조건 Bool 값을 사용하여 마찰력 계산을 If 노드 안에 넣습니다.
  • 불필요한 데이터 인터페이스 호출 자제: 데이터 인터페이스는 외부 데이터를 가져오는 데 비용이 발생합니다. 필요한 경우에만 호출하고, 같은 데이터를 여러 번 가져오기보다 한 번 가져와서 여러 곳에서 재사용하는 것이 좋습니다.

계산량 줄이기

같은 결과를 얻더라도 더 적은 연산으로 얻을 수 있는 방법을 찾아야 합니다.

  • 간단한 수학 연산 선호: Lerp (선형 보간)는 Sine이나 Power 같은 복잡한 수학 함수보다 일반적으로 더 효율적입니다. 가능하다면 간단한 연산으로 대체할 수 있는지 고려해 보세요.
  • 정규화(Normalize)의 오용 주의: Normalize 연산은 제곱근(Sqrt) 계산을 포함하므로 비교적 비용이 큽니다. 벡터의 방향만 필요하고 실제 크기 자체는 필요 없을 때만 사용합니다. 크기 비교를 해야 할 때는 Vector Length 대신 Vector Length Squared를 사용하여 제곱근 계산을 피하는 것이 좋습니다.
    • Vector Length Squared‘Length‘2=x2+y2+z2\text{`Length`}^2 = x^2 + y^2 + z^2 로 계산되어 더 빠릅니다.
  • 상수 vs. 변수: 스크립트 내에서 값이 변하지 않는 상수는 직접 값을 입력하는 것이 좋습니다. 불필요하게 Get 노드를 통해 매 프레임마다 가져오는 것은 작은 오버헤드를 발생시킬 수 있습니다.
  • 복잡한 커브 최소화: 커브는 시각적으로 아름다운 변화를 제공하지만, 너무 많은 키나 복잡한 탄젠트를 가진 커브는 계산 비용을 증가시킬 수 있습니다. 필요한 만큼만 키를 사용하고 부드럽게 유지하세요.

계산을 줄일 때는 먼저 반복 빈도와 파티클 수를 기준으로 비용이 커지는 지점을 찾고, 같은 결과를 더 단순한 노드로 바꿀 수 있는지 확인합니다.

스크립트 비용 줄이는 순서

성능 최적화는 비싼 노드를 찾는 일보다, 자주 실행되는 계산을 먼저 줄이는 일에 가깝습니다.

  1. 1
    매 프레임

    빈도 Update의 계산은 활성 파티클 수만큼 반복됩니다. Update count Particles x Frame

  2. 2
    제곱근 회피

    수학 거리 비교는 길이 대신 제곱 길이로 바꿉니다. Length Length Squared

  3. 3
    DI 재사용

    호출 외부 데이터는 한 번 읽고 여러 계산에 나눠 씁니다. Sample once Reuse value

  4. 4
    조건 제한

    분기 비싼 계산은 필요한 조건에서만 실행합니다. If OnGround Then Friction

  5. 5
    먼저 측정

    `stat Niagara`와 디버거에서 실제 병목을 확인합니다.

  6. 6
    결과 유지

    시각 차이가 작은 대체식부터 적용합니다.

  7. 7
    플랫폼 확인

    모바일, VR, 저사양 프리셋에서 다시 봅니다.

스크립트 최적화는 화면 품질을 유지하면서 계산량을 줄이는 작업이므로, 병목을 찾는 순서를 고정해 두면 좋습니다.

스크립트 비용은 측정에서 LOD까지 한 번에 한 층씩 줄인다

노드를 무작정 지우지 말고 현재 병목을 고정한 뒤 활성 수, 반복 계산, 시뮬레이션 위치, 플랫폼 LOD 순서로 같은 화면 결과를 더 싸게 만든다.

  1. 1
    기준 장면 측정

    Niagara Debugger·stat Niagara·GPU profiler로 가장 비싼 층을 찾는다.

  2. 2
    활성 수 축소

    Spawn Rate·Burst·Lifetime을 줄여도 실루엣이 남는 지점을 고른다.

  3. 3
    반복 계산 제거

    상수와 초기값은 Spawn에서 계산하고 Update는 결과만 읽는다.

  4. 4
    실행 위치 선택

    벤트 연동은 CPU, 대량 독립 입자는 GPU 비용을 비교한다.

  5. 5
    LOD·Cull 적용

    거리와 플랫폼에 따라 Emitter·Collision·Light를 단계적으로 줄인다.

  6. 6
    Profiler

    추측 대신 실제 System·Emitter·Module·Renderer 시간을 본다.

  7. 7
    Bounds

    너무 큰 Fixed Bounds가 컬링을 막지 않는지 확인한다.

  8. 8
    품질 계약

    효과의 역할·타이밍·핵심 실루엣이 유지되어야 통과다.


GPU와 CPU 연산의 이해

나이아가라는 파티클 시뮬레이션을 CPU 또는 GPU에서 수행할 수 있습니다.

각 방식의 장단점을 이해하고 적절히 활용하는 것이 중요합니다.

  • GPU 시뮬레이션 활용
    • 대규모 파티클 효과(수천, 수만 개)에는 GPU 시뮬레이션이 훨씬 효율적입니다. GPU는 병렬 연산에 특화되어 있어, 각 파티클이 독립적으로 계산되는 경우 CPU보다 압도적으로 빠릅니다.
    • 주의: GPU 시뮬레이션은 월드와의 충돌 처리, 블루프린트와의 양방향 통신 등 특정 CPU 기반 기능에 제약이 있을 수 있습니다. 모든 상황에 GPU 시뮬레이션이 최적은 아닙니다. 이미터의 Sim Target 속성을 GPU Compute로 설정하여 변경할 수 있습니다.
  • CPU 시뮬레이션 선택
    • 정확한 충돌 처리, 복잡한 게임 로직과의 연동(블루프린트에서 파티클 데이터 읽기/쓰기), 적은 수의 파티클에는 CPU 시뮬레이션이 더 적합할 수 있습니다.
    • 소규모 효과의 경우 CPU 시뮬레이션의 오버헤드가 크지 않으므로 굳이 GPU로 전환할 필요는 없습니다.

LOD (Level of Detail) 및 스케일러빌리티

나이아가라는 거리에 따라 효과의 복잡도를 자동으로 조절하는 기능을 제공합니다.

  • Scalability 섹션 활용: 이미터의 Scalability 섹션에서 Max Particles, Cull Proxy, LOD Distance 등의 속성을 설정할 수 있습니다.
    • Max Particles: 한 이미터에서 동시에 생성될 수 있는 최대 파티클 수를 제한하여 과도한 파티클 생성을 방지합니다.
    • LOD Distance: 카메라와의 거리에 따라 이미터의 스폰율, 파티클 수, 또는 특정 모듈의 활성화 여부 등을 자동으로 조절하여 멀리 있는 효과는 간단하게 렌더링하도록 합니다. 이를 통해 보이지 않거나 중요하지 않은 효과에 대한 연산 비용을 크게 줄일 수 있습니다.
  • Deactivate after System Last Particle Dies: 시스템 속성에서 이 옵션을 활성화하면, 모든 파티클이 사라진 후 시스템이 자동으로 비활성화되어 불필요한 연산을 방지합니다.

GPU 파티클 스케일러빌리티 주의사항

GPU 시뮬레이션은 강력하지만, 장면 전체에서 무분별하게 사용하면 오히려 프레임 드랍을 키울 수 있습니다.

  • 동시 활성 시스템 수 제한: 강한 효과를 가진 GPU 시스템은 최대 동시 개수를 디자인 단계에서 정하고, 초과 시 저비용 대체 효과로 전환합니다.
  • 오버드로우 관리: 반투명 파티클이 화면을 크게 덮으면 GPU 비용이 급증합니다. 큰 스프라이트 다중 중첩을 피하고, 거리별 알파 감쇠를 적극 사용합니다.
  • 플랫폼별 품질 분기: 모바일/저사양 PC는 스폰율, 최대 파티클 수, 라이트 렌더러 사용 여부를 별도 프리셋으로 분기합니다.
  • 틱 기반 업데이트 최소화: 블루프린트에서 Event Tick마다 파라미터를 밀어 넣기보다 이벤트 기반으로 전환해 CPU-GPU 동기화 비용을 줄입니다.
  • LOD와 컬링 동시 적용: LOD만으로 부족하면 카메라 거리/화면 점유율 기준 컬링 룰을 함께 적용합니다.

프로파일링 도구 활용

어디서 성능 병목 현상이 발생하는지 정확히 파악하는 것이 최적화의 첫걸음입니다.

프로파일링 결과를 어떤 수정 단위로 옮길지 빠르게 판단하려면 아래 기준표를 참고하세요.

프로파일링 결과를 수정 단위로 옮기기

Niagara Debugger, stat Niagara, Unreal Insights에서 보이는 증상을 시스템, 이미터, 모듈, 렌더러 중 어느 레이어에서 줄일지 연결합니다.

  1. 동시 재생 수가 높다

    System Scalability, Auto Deactivate, 플랫폼별 품질 프리셋으로 시스템 단위 비용을 제한합니다.

  2. 파티클 수가 많다

    Emitter Spawn Rate, Max Particles, LOD Distance, Cull Proxy를 조정해 생성량을 먼저 낮춥니다.

  3. Update 계산이 무겁다

    Module 미사용 모듈 삭제, 값 캐싱, 조건 실행으로 매 프레임 계산을 줄입니다.

  4. GPU 시간이 튄다

    Renderer 큰 반투명 스프라이트, 과한 알파 중첩, 라이트 렌더러 사용 여부를 다시 봅니다.

  • 나이아가라 디버거(Niagara Debugger): 나이아가라 에디터의 Debug 패널이나 언리얼 에디터의 Window > Developer Tools > Niagara Debugger를 통해 파티클 수, 프레임 시간, 각 모듈의 비용 등을 실시간으로 확인할 수 있습니다.
  • stat Niagara 콘솔 명령어: 게임 플레이 중 stat Niagara 명령어를 콘솔에 입력하여 나이아가라 시스템의 전체적인 성능 통계를 확인할 수 있습니다.
  • Unreal Insights: 더욱 심층적인 성능 분석을 위해 언리얼 엔진의 프로파일링 도구인 Unreal Insights를 활용하여 CPU/GPU 사용량, 메모리 할당 등을 정밀하게 분석할 수 있습니다.

스크립트 최적화는 한 번에 끝나는 작업이 아니라, 효과를 개발하고 테스트하는 전 과정에 걸쳐 꾸준히 고려해야 할 부분입니다.

위에서 언급된 기본 기법들을 숙지하고 실제 작업에 적용함으로써, 여러분은 시각적으로 훌륭하면서도 성능적으로 효율적인 나이아가라 효과를 만들어낼 수 있을 겁니다.

아래 다이어그램은 나이아가라 스크립트의 병목을 발견했을 때 어떤 최적화 수단부터 적용할지 정리한 우선순위 지도입니다.

Niagara 최적화 우선순위 지도

최적화는 먼저 측정하고, 가장 큰 비용부터 줄이는 작업이다. 파티클 수, 머티리얼, 실행 위치, 컬링 기준을 같은 화면에서 비교해야 품질 손실을 줄일 수 있다.

  1. Measure

    Debugger와 stat 값으로 병목을 찾는다.

  2. Count

    Spawn Rate와 Lifetime을 함께 본다.

  3. Material

    오버드로우와 라이트 비용을 낮춘다.

  4. Runtime

    CPU와 GPU 실행 제약을 비교한다.

  5. Cull

    거리, 화면 점유율, 플랫폼으로 끊는다.

병목 신호먼저 줄일 값확인 도구주의점
입자 수 과다Spawn Rate, LifetimeNiagara Debugger밀도가 갑자기 비지 않게 LOD 적용
GPU 과부하오버드로우, 라이트, 큰 스프라이트Unreal Insights투명 파티클 중첩 확인
CPU 과부하Tick 전달, 이벤트, 데이터 호출stat NiagaraGPU 전환 가능 여부 확인