PART 7 · 강의 1/3

애니메이션 LOD와 Update Rate

Anim LOD, Update Rate Optimization (URO), SignificanceManager, Visibility 기반 최적화를 분석합니다.

SECTION 01

애니메이션 LOD 시스템

거리/화면 크기에 따른 애니메이션 품질 단계적 축소

애니메이션 LOD는 메시 LOD와 연동하여, 먼 거리의 캐릭터는 적은 본으로 평가하거나 애니메이션 업데이트를 줄여 CPU 비용을 절감하는 시스템입니다.

Animation LOD 단계
LOD 0 (가까움): - 모든 본 평가 (150+ 본) - 매 프레임 업데이트 - IK, Control Rig, 물리 애니메이션 모두 활성 - 풀 품질 블렌딩 LOD 1 (중간): - 필수 본만 평가 (80~100 본) - 2프레임마다 업데이트 (URO) - IK 간소화, 물리 비활성 - 간소화된 블렌딩 LOD 2 (멀리): - 최소 본만 평가 (30~50 본) - 4프레임마다 업데이트 - IK, Control Rig 비활성 - 단순 포즈 스냅 LOD 3+ (매우 멀리): - 애니메이션 업데이트 중지 - 마지막 포즈 유지 또는 비가시 처리
LOD 설정 설명 위치
BonesToRemove LOD별 제거할 본 목록 USkeletalMesh LOD Settings
RequiredBones LOD별 필수 본 인덱스 배열 FSkeletalMeshLODRenderData
ScreenSize LOD 전환 화면 크기 비율 FSkeletalMeshLODInfo
SECTION 02

Update Rate Optimization (URO)

애니메이션 업데이트 빈도를 동적으로 조절하는 URO 시스템

URO (Update Rate Optimization)는 화면 크기, 거리, 가시성에 따라 애니메이션 업데이트 빈도를 줄이는 최적화입니다. 먼 캐릭터는 매 프레임 대신 2~8프레임마다 업데이트하여 CPU를 절감합니다.

C++
// URO 설정 void AMyCharacter::SetupURO() { USkeletalMeshComponent* Mesh = GetMesh(); // URO 활성화 Mesh->bEnableUpdateRateOptimizations = true; // 보간 활성화 (업데이트 스킵 프레임에서 보간) Mesh->bDisplayDebugUpdateRateOptimizations = false; // AnimUpdateRateTick 설정 // 자동으로 ScreenSize 기반 업데이트 레이트 결정 } // 콘솔 변수로 전역 설정 // a.URO.Enable 1 // a.URO.ForceAnimRate 0 (0=자동, N=N프레임마다) // a.URO.DrawDebug 1 (디버그 시각화) // 프로젝트 설정에서 URO 임계값 조정 // Engine → Animation → Update Rate Optimizations // MaxEvalRateForInterpolation: 4 // BaseNonRenderedUpdateRate: 4 // BaseVisibleDistanceFactorThresholds: [0.4, 0.2, 0.1]
URO 보간(Interpolation)

URO가 프레임을 스킵할 때, 보간 없이는 캐릭터가 뚝뚝 끊기는 것처럼 보입니다. bInterpolateSkippedFrames를 활성화하면 스킵된 프레임에서 이전/다음 포즈 사이를 보간하여 시각적 끊김을 줄입니다. 다만 보간 자체에도 약간의 비용이 있으므로, 매우 먼 거리에서는 보간도 비활성화하는 것이 효율적입니다.

SECTION 03

SignificanceManager

중요도 기반 애니메이션 리소스 할당 시스템

SignificanceManager는 각 액터/컴포넌트의 "중요도(Significance)"를 실시간으로 평가하여, 중요도가 높은 객체에 더 많은 리소스를 할당하는 시스템입니다.

C++
// SignificanceManager 연동 class AMyCharacter : public ACharacter { virtual void BeginPlay() override { Super::BeginPlay(); // SignificanceManager에 등록 USignificanceManager* SigMgr = FModuleManager::Get().GetModulePtr<USignificanceManager>("SignificanceManager"); if (SigMgr) { SigMgr->RegisterObject( this, FName("Character"), // 중요도 계산 함수 [](USignificanceManager::FManagedObjectInfo* Info, const FTransform& ViewPoint) -> float { AActor* Actor = Cast<AActor>(Info->GetObject()); float Distance = FVector::Dist(Actor->GetActorLocation(), ViewPoint.GetLocation()); // 거리 기반 중요도 (0~1) return FMath::Clamp(1.0f - (Distance / 10000.f), 0.f, 1.f); }, // Post 중요도 처리 USignificanceManager::EPostSignificanceType::Sequential ); } } // Significance 결과에 따른 애니메이션 품질 조정 void OnSignificanceChanged(float NewSignificance) { if (NewSignificance > 0.7f) { // 고품질: 풀 애니메이션 GetMesh()->SetComponentTickInterval(0.f); EnableIK(true); } else if (NewSignificance > 0.3f) { // 중간: URO + IK 간소화 GetMesh()->SetComponentTickInterval(0.033f); // 30fps EnableIK(false); } else { // 저품질: 최소 업데이트 GetMesh()->SetComponentTickInterval(0.1f); // 10fps } } };
SECTION 04

가시성 기반 최적화

화면 밖 캐릭터의 애니메이션 처리 전략

VisibilityBasedAnimTickOption

AlwaysTickPoseAndRefreshBones: 항상 업데이트. AlwaysTickPose: 포즈만 업데이트. OnlyTickPoseWhenRendered: 화면에 보일 때만 업데이트.

Occlusion Culling

다른 오브젝트에 가려진 캐릭터는 렌더링과 애니메이션을 모두 스킵합니다. 하드웨어 오클루전 쿼리 기반입니다.

Pause Anim When Not Visible

보이지 않을 때 애니메이션을 완전히 일시정지합니다. 다시 보이면 현재 시간에 맞춰 점프하여 재생합니다.

Reduced Bone Pool

화면 밖에서는 게임플레이에 필요한 최소 본(루트, 소켓 본)만 업데이트하여 사운드, AI 등에 활용합니다.

60%
URO로 절감 가능한 평균 CPU 비용
40%
본 축소로 절감 가능한 스키닝 비용
80%
화면 밖 스킵으로 절감 가능한 비용
SUMMARY

핵심 요약

  • 애니메이션 LOD는 거리에 따라 본 수, 업데이트 빈도, IK/물리 활성화를 단계적으로 축소한다.
  • URO는 화면 크기 기반으로 업데이트 빈도를 자동 조절하며, 보간으로 시각적 끊김을 줄인다.
  • SignificanceManager로 중요도를 실시간 평가하여, 중요한 캐릭터에 더 많은 애니메이션 리소스를 할당한다.
  • VisibilityBasedAnimTickOption으로 화면 밖 캐릭터의 애니메이션을 일시정지하여 대폭 절감할 수 있다.
  • URO(60%) + 본 축소(40%) + 화면 밖 스킵(80%)을 조합하면 대규모 캐릭터 환경에서 실질적인 최적화를 달성한다.
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: Anim LOD 설정

AnimBP의 LOD Threshold 설정에서 LOD별로 사용할 AnimGraph 브랜치를 분리하세요. LOD 0에서는 Full Body IK + Blend Space, LOD 2에서는 단순 State Machine만 사용하도록 구성하고, LOD 전환 시 시각적 차이를 확인하세요.

실습 2: URO(Update Rate Optimization) 적용

SkeletalMeshComponent의 AnimUpdateRateParams를 설정하세요. 카메라와의 거리에 따라 Tick Rate를 조절하고(가까이: 매 프레임, 중간: 2프레임마다, 멀리: 4프레임마다), 보간을 활성화하여 낮은 업데이트 레이트에서도 부드러워 보이도록 하세요.

심화 과제

100개의 NPC가 있는 씬에서 SignificanceManager를 활용한 종합 최적화를 구현하세요. 중요도에 따라 Tick 비활성화, LOD 강제, 본 제거를 적용하고, stat anim 명령으로 최적화 전후의 애니메이션 비용을 정량적으로 비교하세요.