LOD 시스템
Visualization, Simulation, Replication의 3중 LOD 시스템을 이해합니다
3중 LOD 체계
시각화, 시뮬레이션, 리플리케이션의 독립적 LOD
Mass Entity의 LOD 시스템은 세 가지 독립적인 LOD로 구성됩니다. 각각 다른 목적으로 최적화를 수행합니다.
| LOD 타입 | 목적 | 4단계 |
|---|---|---|
| Visualization LOD | 시각적 표현 품질 제어 | Full Actor → Low Actor → ISM → None |
| Simulation LOD | 로직 연산 빈도 제어 | 매 틱 → 격틱 → 저빈도 → 정지 |
| Replication LOD | 네트워크 전송 빈도 제어 | 고빈도 → 중빈도 → 저빈도 → 없음 |
// LOD Significance 값 (0.0 ~ 3.0)
//
// High = 0.0 ~ 1.0 (카메라 가까움, 화면 중앙)
// Medium = 1.0 ~ 2.0 (중거리, 화면 가장자리)
// Low = 2.0 ~ 3.0 (원거리)
// Off = 3.0+ (최원거리 또는 시야 밖)
//
// Significance 계산 요소:
// 1. 카메라까지의 거리
// 2. 시야각(Frustum) 내 위치
// 3. 오클루전(Occlusion) 상태
Simulation LOD
먼 엔티티의 연산 빈도를 줄여 CPU 부하 절감
Simulation LOD는 시각화와 독립적으로, 엔티티의 로직 실행 빈도를 조절합니다. 멀리 있는 엔티티는 매 프레임이 아닌 몇 프레임마다 한 번 처리됩니다.
// Simulation LOD 단계별 처리 빈도
//
// High: 매 틱 실행 (Full Rate)
// → 카메라 주변의 핵심 엔티티
//
// Medium: 2~4 틱마다 1회 (Half Rate)
// → 중거리 엔티티
//
// Low: 8~16 틱마다 1회 (Low Rate)
// → 원거리 엔티티
//
// Off: 처리하지 않음 (Dormant)
// → 시야 밖이나 매우 먼 엔티티
// → 데이터는 유지, 로직만 정지
// Variable Tick Rate Processor 패턴
void UMySimProcessor::ConfigureQueries()
{
SimQuery.AddRequirement<FTransformFragment>(
EMassFragmentAccess::ReadWrite);
SimQuery.AddRequirement<FMassSimulationLODFragment>(
EMassFragmentAccess::ReadOnly);
SimQuery.RegisterWithProcessor(*this);
}
void UMySimProcessor::Execute(
FMassEntityManager& EntityManager,
FMassExecutionContext& Context)
{
SimQuery.ForEachEntityChunk(EntityManager, Context,
[](FMassExecutionContext& Ctx)
{
const auto LODs = Ctx.GetFragmentView
<FMassSimulationLODFragment>();
for (int32 i = 0; i < Ctx.GetNumEntities(); ++i)
{
// Off 상태면 처리 건너뛰기
if (LODs[i].LOD == EMassLOD::Off)
continue;
// LOD에 따라 처리 빈도 조절
if (LODs[i].LOD == EMassLOD::Low &&
!LODs[i].ShouldTickThisFrame())
continue;
// 실제 로직 처리
ProcessEntity(Ctx, i);
}
});
}
10,000 엔티티 중 가까운 100개만 매 틱 처리하고, 나머지 9,900개를 4~16틱마다 처리하면 CPU 부하가 약 1/4~1/16로 감소합니다. 사용자는 거의 차이를 느끼지 못합니다.
Replication LOD
네트워크 멀티플레이어에서의 LOD 기반 대역폭 최적화
Replication LOD는 멀티플레이어 환경에서 각 클라이언트에 대해 엔티티의 네트워크 전송 빈도를 결정합니다.
// 각 클라이언트별로 독립적인 Replication LOD
//
// 서버: 10,000 엔티티 시뮬레이션
//
// 클라이언트 A (카메라 위치 기준):
// High: 50개 → 매 틱 전송 (30Hz)
// Med: 200개 → 10Hz 전송
// Low: 500개 → 2Hz 전송
// Off: 9250개 → 전송 안 함
//
// 클라이언트 B (다른 위치):
// High: 80개 → 30Hz
// Med: 150개 → 10Hz
// Low: 400개 → 2Hz
// Off: 9370개 → 전송 안 함
//
// → 각 클라이언트가 실제로 수신하는 데이터는
// 전체의 약 7~8%에 불과
Mass Replication은 실험적 기능입니다. 서버→클라이언트 단방향 전송만 지원하며, 커스텀 값 리플리케이션은 C++ 구현이 필요합니다. 프로덕션 사용 시 충분한 테스트가 필요합니다.
LOD 설정 튜닝
프로젝트에 맞는 LOD 거리와 설정 조정
시가지 (City)
- High: 0~30m
- Medium: 30~150m
- Low (ISM): 150~800m
- Off: 800m+
- Actor Pool: 80
개활지 (Open)
- High: 0~50m
- Medium: 50~300m
- Low (ISM): 300~2000m
- Off: 2000m+
- Actor Pool: 50
// 런타임에서 LOD 거리 조정 (CVar)
//
// mass.lod.HighDistance 50
// mass.lod.MediumDistance 200
// mass.lod.LowDistance 1000
// mass.lod.OffDistance 5000
//
// 시뮬레이션 LOD 빈도
// mass.SimLOD.MediumTickRate 2 (2틱마다 1회)
// mass.SimLOD.LowTickRate 8 (8틱마다 1회)
stat Mass와 Unreal Insights로 프레임 타임을 측정하면서 LOD 거리를 조정하세요. 목표 프레임레이트를 유지하면서 가능한 한 많은 엔티티를 높은 품질로 표시하는 균형점을 찾는 것이 핵심입니다.
핵심 요약
- Mass Entity의 LOD는 Visualization, Simulation, Replication 세 가지가 독립적으로 동작한다
- 각 LOD는 High, Medium, Low, Off의 4단계로 구분되며, Significance 값(0.0~3.0)으로 계산된다
- Simulation LOD는 먼 엔티티의 로직 실행 빈도를 줄여 CPU 부하를 1/4~1/16로 절감한다
- Replication LOD는 클라이언트별로 네트워크 전송 빈도를 조절하여 대역폭을 최적화한다
- LOD 거리와 설정은 CVar로 런타임 조정이 가능하며, 프로파일링 기반 튜닝이 필수이다
- 환경 특성(시가지/개활지)에 따라 LOD 거리와 Actor Pool 크기를 다르게 설정한다
도전 과제
배운 내용을 직접 실습해보세요
MassLOD Trait에서 각 LOD 레벨(High, Medium, Low, Off)의 거리 임계값을 설정하세요. Off 거리 이상의 엔티티는 시뮬레이션도 중단되는 것을 확인하세요.
Processor에서 FMassLODFragment의 LOD 레벨을 읽어, High에서는 정밀한 물리, Medium에서는 간소화된 이동, Low에서는 위치만 업데이트하는 LOD 기반 시뮬레이션 분기를 구현하세요.
전체 프레임 예산을 기반으로 LOD 거리를 동적으로 조절하는 시스템을 만드세요. 엔티티가 많아지면 LOD 거리를 자동으로 줄이고, 적어지면 늘리는 적응형 LOD를 구현하세요.