[UE4] Physics Sub-stepping(피직스 서브스테핑)에 대한 정리 (1 / 2)
#언리얼4 공부중 / UE4 버젼: 4.22.3 / 피드백 환영
Physics Sub-stepping은 문자 그대로 보면, 물리 엔진의 작업 스텝을 서브 스텝으로 나눠서 작업이 행해진 다는 의미를 담고 있는 듯 하다. 무슨 소린지 어렵다. 일단 물리로 오브젝트를 다루려면 물리 프레임을 기반으로 게임상의 오브젝트들도 동작하여야 한다. 유니티에서는 FixedUpdate가 그 역할을 담당하는데, 언리얼에서는 fixed frame에 대한 개념이 유니티보다 더 기능이 많아 보인다.
관련 용어 정리가 필요하다.
- Fixed Frame Rate
- Smooth Frame Rate
- Min Desired Frame Rate
- Max Physics Delta Time
- Substepping
- Max Substep Delta Time
- Max Substeps
메뉴의 Project Settings > Engien > General Settings > Framerate 그리고 Project Settings > Engine > Physics 에서 위의 정의된 Property를 설정할 수 있다. 이 용어에 대한 정의를 하기 전에 상관 관계를 먼저 구분해 보면 아래와 같이 나눌 수 있다.
Fixed Frame Rate <———> Smooth Frame Rate / Min Desired Frame Rate
MaxPhysics Delta Time <———-> Substepping
프로젝트 세팅에서 각 옵션을 클릭해보면 알 수 있는 데, Fixed Frame Rate와 Smooth Frame Rate는 동시에 선택할 수 없다. Max Physics Delta Time과 Substepping도 서로 반한는 것이기 때문에 하나만 선택할 수 있다.
Fixed Frame Rate은 언리얼 엔진으로 부터 고정된 간격(fixed delta time)으로 Tick 함수 호출을 받기 위한 값이다. 60.0으로 세팅할 경우 1/60 = 0.01666 sec의 delta time을 Tick 함수를 통해 받고, 물체를 시뮬레이션 할 수 있다. 60 프레임의 게임을 추구하고 안정적인 렌더링 프레임 레이트를 보장한다면 설정하여 쓸 수 있지만, 실제 게임상에서 렌더링이 30프레임밖에 나오지 않는데, Fixed Frame Rate을 60으로 설정한 경우에는 1/30 = 0.03333 sec 의 delta time이 되어야 하지만 0.01666 sec가 되어, AddForce(vel * deltaTime)일 경우 오브젝트에 대한 힘이 실제와 달리 1/2로 줄어들어 표현된다.
Smooth Frame Rate의 경우는 Fixed Frame Rate와는 달리 min/max 범위로 허용 프레임을 설정하고, 이는 vsync를 통해 발생될 수 있는 찢어지는 현상이나 잠깐씩 멈추는 현상을 어플리케이션 레벨에서 막을 수 있다고 한다. Fixed Frame Rate를 사용하지 않는다면 일단 Smooth Frame Rate을 사용해야 하는건 당연한 선택으로 보인다. Smooth Frame Rate에 대해서는 포럼에서도 설명된 글이 있으니 참고하면 좋을 것 같다.
Min Desired Frame Rate의 경우 Fixed Frame Rate이나 Smooth Frame Rate을 사용하지 않지만, 최소 지정된 프레임 레이트를 보장해 주는 것으로 보이지만, 실제 테스트를 해보면 어떻게 영향을 주는지는 알기 힘들었다. 값을 설정해도 그 이상의 delta time이 넘어오고 있었고, 관련해서 메뉴얼을 찾을 수가 없었다.
Max Physics Delta Time은 물리 엔진과 관련된 프레임 레이트이다. 이 시간은 렌더링 프레임 레이트와도 관련이 있다. 즉 0.016666 sec (60fps)로 설정한다면, 렌더링 프레임이 0.0125 sec (80fps)라고 할지라도, 물리적인 delta time은 0.01666 sec로 유지한다는 말이다. 그래서 렌더링 프레임이 높게 나오는 상황에서 일관적인 물리 효과를 주기에는 좋지만, 만약 렌더링 프레임이 0.03333 sec (30fps)이 나오는 상황에서는 0.01666sec의 delta time은 실제와 다른 효과를 보여준다. 실제로 0.03333 sec (30fps)의 효과를 주려면 0.01666 sec가 두번 tick이 호출되어야 하기 때문이다. 여기서 서브스테핑의 기능이 효과를 발하는데, 두번 호출하게 하려면 Sub-Stepping을 2로 설정하면 된다.
Substepping을 켜게 되면 Max Physics Delta Time은 disable 처리된다. 그럼 설정할 수 있는 값이 Max Substep Delta Time과 Max Substeps이 나오는데, 위와 같이 렌더링 프레임 레이트가 30fps가 나오는 상황에서 두번의 물리 tick 호출을 일으키게 하려면 Max Substep Delta Time을 0.016으로, Max Substeps을 2로 설정하면 된다. Max값이기 때문에 렌더링 프레임이 60fps로 나오는 상황에서는 Substeps이 2일지라도 물리 tick은 한번만 호출된다.
아래 로그는 Tick 함수 호출과 물리 Tick 함수 호출시를 나타낸다. 렌더링 프레임이 일시적으로 떨어질 경우 Substep Tick이 두번 호출되는 것을 볼 수 있다.
LogTemp: Warning: [Tick] DeltaTime=0.008337
LogTemp: Warning: [SubstepTick] DeltaTime=0.008337
LogTemp: Warning: [Tick] DeltaTime=0.400000
LogTemp: Warning: [SubstepTick] DeltaTime=0.016000
LogTemp: Warning: [SubstepTick] DeltaTime=0.016000
LogTemp: Warning: [Tick] DeltaTime=0.012291
LogTemp: Warning: [SubstepTick] DeltaTime=0.012291
LogTemp: Warning: [Tick] DeltaTime=0.008334
LogTemp: Warning: [SubstepTick] DeltaTime=0.008334
LogTemp: Warning: [Tick] DeltaTime=0.008334
LogTemp: Warning: [SubstepTick] DeltaTime=0.008334
LogTemp: Warning: [Tick] DeltaTime=0.008333
LogTemp: Warning: [SubstepTick] DeltaTime=0.008333
LogTemp: Warning: [Tick] DeltaTime=0.008334
LogTemp: Warning: [SubstepTick] DeltaTime=0.008334
Substepping Async는 4.22.3에서는 실험적인 기능으로 나오므로 일단 스킵해본다.
아래 링크에서는 Physics Sub-stepping에 대한 정보를 더 많이 얻을 수 있으므로 참고하면 좋다.
다음편(2/2)에서 샘플 코드를 작성해보자.
- References
- Everything you always wanted to know about Unreal Engine physics (http://www.aclockworkberry.com/unreal-engine-substepping/)
- Framerate independent physics in UE4 (https://avilapa.github.io/post/framerate-independent-physics-in-ue4/)