본문 바로가기

물리 시뮬레이션 성능 조정

충돌 형상·활성 물체·서브스텝과 수면 상태를 조정하고 프로파일러로 물리 시뮬레이션의 CPU 병목을 줄입니다.

물리 상호작용을 늘리면 게임은 풍부해지지만, 성능이 가장 먼저 흔들립니다. 많은 물체가 동시에 부딪히거나 충돌 형상이 복잡하면 CPU 비용이 갑자기 올라가 프레임이 불안정해집니다. 폭발로 파편 수백 개가 흩어지는 순간에만 프레임이 뚝 떨어지는 일이 대표적입니다.

이 글에서는 물리 시뮬레이션이 성능에 어떤 영향을 주는지 정리하고, 충돌 형상을 단순하게 하고, 시뮬레이션할 물체를 관리하고, 서브스텝을 조정하는 방법을 차례로 살펴봅니다. 그다음 물리 비용을 측정하는 도구와 비교하는 순서를 익히고, 서브스텝의 단계 수를 계산해 봅니다. 이 글을 마치면 물리의 품질과 성능 사이에서 프로젝트에 맞는 균형을 직접 정할 수 있습니다.


물리 비용은 어디서 생기나

이 글에서 다루는 카오스 강체 시뮬레이션은 주로 CPU에서 계산됩니다. 화면에 그리는 비용과 디버그 표시의 GPU 비용은 따로 측정해야 합니다. 물리 비용은 특히 많은 물체가 동시에 상호작용할 때 병목이 되기 쉽습니다.

물리 성능을 관리해야 하는 이유는 여러 가지입니다. 물리 때문에 프레임이 떨어지면 플레이 경험이 크게 나빠지므로, 어떤 상황에서도 목표 프레임을 지켜야 합니다. CPU와 GPU, 메모리 같은 한정된 자원을 효율적으로 써야 고사양 PC뿐 아니라 콘솔과 모바일에서도 게임이 원활하게 돌아갑니다. 또 물리를 잘 관리하면 물체가 뚫리거나 떨리는 물리 버그도 줄어 게임 플레이가 일관되게 유지됩니다.

물리 최적화는 화면에 보이는 물체와 실제로 물리 계산이 필요한 물체를 구분하는 데서 시작합니다. 보이는 모든 것이 물리로 움직일 필요는 없기 때문입니다.


충돌 형상을 단순하게

충돌 형상과 접촉의 수는 물리 비용에 영향을 줍니다. 다만 그것이 지금 가장 큰 병목인지는 측정으로 확인합니다.

대부분의 스태틱 메시는 상자, 구, 캡슐, 볼록 껍질 같은 간단한 형태로 충돌을 계산하는 단순 충돌을 써야 합니다. 단순 충돌은 계산이 매우 효율적이며, 스태틱 메시 에디터의 Collision 메뉴에서 자동으로 만들거나 직접 더할 수 있습니다.

메시의 실제 폴리곤을 쓰는 복잡 충돌은 매우 정확하지만 비용이 큽니다. Use Complex as Simple은 필요한 접촉의 정확도와 비용을 비교한 뒤 고르며, 이렇게 설정한 메시는 물리 시뮬레이션을 할 수 없다는 점도 기억합니다. 예외로 복잡한 절벽 지형처럼 단순 충돌로 비슷하게 만들기 어렵고 플레이어가 직접 밟고 다녀야 하는 아주 큰 정적 메시에는 Use Complex as Simple을 고려할 수 있습니다. 지형의 형태에 따라 랜드스케이프와 비교해 볼 수도 있지만, 랜드스케이프가 동굴이나 절벽 같은 구조를 모두 대신할 수 있는 것은 아닙니다.


시뮬레이션할 물체 관리하기

모든 물체가 늘 물리 시뮬레이션을 할 필요는 없습니다. Simulate Physics는 실제로 물리 상호작용이 필요한 물체에만 켜고, 정적인 배경이나 미리 애니메이션으로 움직이는 물체에는 끕니다.

동시에 시뮬레이션하는 물체의 수도 관리합니다. 화면 밖에 있는 물체도 시뮬레이션 중이라면 비용이 들기 때문입니다. 폭발 같은 이벤트로 파편이 생길 때는, 파편의 수와 시뮬레이션하는 시간을 제한하는 로직을 블루프린트나 C++로 만듭니다. 예를 들어 파편이 일정 시간 뒤에 사라지게 하거나, 동시에 있을 수 있는 파편의 최대 수를 정해 둡니다.

잠들기

물리 엔진은 거의 움직이지 않는 물체를 자동으로 잠들기(sleep) 상태로 바꿉니다. 잠든 물체는 움직임을 계산하고 접촉을 푸는 비용이 줄어들지만, 충돌 정보와 다시 깨어날 조건까지 사라지는 것은 아닙니다. 그래서 다른 물체가 부딪히면 다시 깨어나 움직입니다. 잠들기는 물리 비용을 줄이는 중요한 요소입니다.

물리 시뮬레이션을 켠 액터의 디테일 패널 Physics 항목에는 Start Awake 옵션이 있습니다. 기본으로 켜져 있어서 물체가 생기자마자 바로 시뮬레이션을 시작합니다. 생겨나는 순간 가만히 있어야 하는 물체라면 이 옵션을 꺼서 처음부터 잠든 상태로 둘 수 있습니다. 필요할 때는 Wake Rigid Body로 깨우고, 멈춘 물체가 실제로 잠들었는지 확인합니다. 이때 충돌이나 힘을 받아 깨어나는 것과, 잠들고 깨어날 때 이벤트로 알림을 받는 설정은 서로 다른 것이므로 구분합니다.


서브스텝 조정하기

서브스텝은 프로젝트 전체의 물리 설정에서 충돌의 정확도와 성능 사이의 균형을 맞추는 설정입니다. Edit 메뉴의 Project Settings에서 Engine의 Physics에 있습니다.

Enable Substepping을 켜면 한 프레임의 물리 계산을 작은 단계로 나눠, 빠른 물체가 서로 뚫고 지나가는 터널링을 줄이고 시뮬레이션을 안정시킵니다. 대신 계산을 더 많이 하므로 비용이 커집니다. 그래서 꼭 필요할 때만 켜고, Max Substep Delta Time과 Max Substeps를 알맞게 조절합니다. Max Substep Delta Time을 너무 작게 하면 단계 수가 늘어나고, Max Substeps를 너무 크게 하면 프레임이 크게 떨어질 수 있으므로, 기본값을 유지하거나 조금씩만 조절하는 편이 좋습니다.

여기서 Max Substep Delta Time은 CPU가 계산에 쓸 실행 시간의 예산이 아니라, 시뮬레이션이 한 단계에 진행할 시간 간격이라는 점에 주의합니다. 계산해 봅니다. 이번 프레임에 물리로 진행할 시간이 0.03초이고, 각 단계를 0.01초 이하로 나누려면 0.03 ÷ 0.01 = 최소 3단계가 필요합니다. 그런데 Max Substeps가 2라면 두 조건을 동시에 만족할 수 없습니다. 이럴 때는 엔진이 어떤 시간 제한을 적용하는지와 실제로 몇 단계로 나눠 계산했는지를 확인해야 합니다.

더 깊이: 단계 수가 모자랄 때와 충돌 알림의 순서

물리 서브스텝 문서는 이 질문에 답을 줍니다. 한 스텝이 0.05초이고 Max Substep Delta Time이 0.025초라면 스텝은 서브스텝 두 개로 나뉩니다. 그런데 스텝이 길어서 Max Substeps보다 많은 단계가 필요해지면, 엔진은 단계를 계속 늘리지 않고 Max Substeps의 수로 스텝을 고르게 나눕니다. 앞의 예라면 0.03초를 2단계로 나누어 한 단계가 0.015초가 되므로, Max Substep Delta Time인 0.01초보다 긴 단계로 계산됩니다. 그리고 물리 스텝 하나가 진행할 수 있는 시간 자체는 Max Physics Delta Time이 제한합니다.

서브스텝은 사용자에게 드러나지 않게 처리되므로, 엔진이 안에서 맞춰 주는 일도 있습니다. 한 프레임 동안 힘을 가했는데 그 프레임이 N개의 서브스텝으로 나뉘었다면, 같은 가속을 얻도록 N번의 시뮬레이션 단계에 모두 힘을 적용하고, 목표 위치를 정했다면 여러 서브스텝에 걸쳐 보간합니다. 반면 충돌 알림은 주의해서 읽어야 합니다. 서브스텝은 별도의 물리 스레드에서 실행되고 충돌 콜백은 마지막 서브스텝이 끝날 때까지 미뤄지므로, 한 프레임에 같은 충돌에 대한 알림을 여러 번 받을 수 있습니다. 예를 들어 A가 B에 부딪혀 튕겨 나가면 같은 프레임에 겹침이 시작됐다는 알림과 끝났다는 알림을 함께 받을 수 있으며, 알림은 서브스텝의 순서대로 처리됩니다.

물리 재질과 밀도

물리 재질 에셋의 개수만으로 물리 비용을 판단할 수는 없습니다. 다만 Friction과 Restitution을 지나치게 극단적인 값으로 정하면 시뮬레이션이 불안정해지거나 계산할 것이 늘어날 수 있으므로 현실적인 값을 지킵니다. Density를 지나치게 바꾸면 질량 계산에 영향을 줘, 예상하지 못한 물리 반응이 생길 수 있습니다.


물리 비용 측정하기

물리 문제를 진단하고 최적화할 때는 엔진에 들어 있는 도구를 씁니다. 먼저 충돌 형상은 뷰포트의 Show 메뉴에서 Collision을 켜고, 스태틱 메시 에디터의 Simple Collision과 Complex Collision 표시로 실제 형상을 확인합니다. 표시된 색만으로 종류를 단정하지 않습니다.

카오스 비주얼 디버거(Chaos Visual Debugger)는 이를 지원하는 버전에서 물리의 기록을 모아, 바디와 접촉, 시간에 따른 상태를 확인하게 해 줍니다. UE4의 PhysX용 PXVIS 명령은 UE5의 카오스에 쓰는 명령이 아니므로 쓰지 않습니다.

언리얼 인사이트(Unreal Insights)에서는 같은 장면의 CPU 시간 가운데 물리 작업이 얼마나 차지하는지 비교합니다. stat physics는 그 빌드가 제공하는 통계를 빠르게 보는 보조 수단이며, 표시되는 항목은 버전마다 다릅니다. 반면 stat scenerendering과 ProfileGPU는 렌더링과 GPU 비용을 보는 도구이므로, 이것을 강체 계산의 CPU 시간으로 읽지 않습니다.

비교할 때는 측정하는 장면과 물체의 수를 고정합니다. 그리고 활성 바디의 수, 충돌 형상, CCD, 서브스텝 가운데 한 항목만 바꾼 뒤, 같은 상호작용에서 시간과 접촉의 품질을 다시 비교합니다.


더 적극적으로 줄이는 방법

복잡 충돌을 쓰는 메시라면 LOD For Collision으로 복잡 충돌에 쓸 LOD 하나를 고를 수 있습니다. 더 낮은 LOD를 고르면 충돌에 쓰는 폴리곤이 줄어듭니다. 다만 화면 거리에 따라 렌더링 LOD가 바뀔 때 충돌 LOD도 함께 바뀌는 방식은 아닙니다.

물리 시뮬레이션을 켜고 끄는 로직을 직접 만들 수도 있습니다. 물체가 플레이어에게서 멀어지거나 중요도가 낮아지면 시뮬레이션을 끄고, 다시 가까워지면 켜는 식입니다. 엔진의 잠들기보다 더 적극적으로 비용을 줄이는 방법이며, 블루프린트나 C++로 만듭니다.

아주 빠른 물체에는 CCD를 씁니다. 물리 시뮬레이션을 켠 액터의 디테일 패널에서 Collision 항목의 고급(Advanced) 설정을 펼쳐 Use CCD를 켜면 터널링의 위험이 줄어듭니다. 다만 비용이 있으므로 총알이나 빠른 차량처럼 꼭 필요한 물체에만 켭니다.


정리

  • 카오스 강체 시뮬레이션은 주로 CPU 비용이며, 렌더링과 GPU 비용은 따로 측정합니다.
  • 대부분의 메시는 단순 충돌을 쓰고, Use Complex as Simple은 정밀함이 꼭 필요한 정적 메시에만 고르며, 그런 메시는 물리 시뮬레이션을 할 수 없습니다.
  • Simulate Physics는 실제로 필요한 물체에만 켜고, 파편 같은 물체는 수와 시간을 제한합니다.
  • 잠든 물체는 계산 비용이 줄지만 충돌과 깨어날 조건은 남으며, Start Awake를 끄면 처음부터 잠든 상태로 시작합니다.
  • 서브스텝은 터널링을 줄이지만 비용을 늘리며, Max Substep Delta Time은 CPU 예산이 아니라 한 단계의 시뮬레이션 시간 간격입니다.
  • 충돌 형상은 Show 메뉴의 Collision으로, 물리 기록은 카오스 비주얼 디버거로, CPU 시간은 언리얼 인사이트로 보고, 한 항목씩 바꿔 비교합니다.
  • LOD For Collision은 복잡 충돌에 쓸 LOD 하나를 고르는 설정이며, CCD는 아주 빠른 물체에만 켭니다.

연습 문제

1. 몇 단계가 필요할까

이번 프레임에 물리로 진행할 시간이 0.02초이고, 각 단계의 최대 간격이 0.005초라면 최소 몇 단계로 나눠야 할까요? 그렇다면 물리 비용은 서브스텝이 없을 때의 정확히 4배일까요?

해설 보기

0.02 ÷ 0.005 = 4이므로 최소 4단계가 필요합니다.

하지만 이 수는 필요한 단계의 수를 계산한 것일 뿐, 비용이 정확히 4배라는 뜻은 아닙니다. 단계마다 드는 비용은 접촉의 수와 잠든 물체, 계산 조건에 따라 달라지기 때문입니다. 같은 접촉 상황에서 물리 CPU 시간과 함께 물체의 떨림이나 뚫림이 줄었는지를 비교해 확인합니다.

2. 폭발 뒤에만 떨어지는 프레임

수류탄이 터지면 파편 300개가 생기고, 그 뒤 몇 초 동안 프레임이 크게 떨어집니다. 파편은 모두 Simulate Physics가 켜져 있고, 복잡 충돌을 씁니다. 어떤 순서로 비용을 줄여 볼 수 있을까요?

해설 보기

먼저 파편의 충돌을 단순 충돌로 바꿉니다. 복잡 충돌인 메시는 물리 시뮬레이션에 알맞지 않고 비용도 큽니다. 그다음 동시에 있을 수 있는 파편의 최대 수를 정하고, 일정 시간이 지나면 파편이 사라지거나 시뮬레이션을 끄게 하는 로직을 더합니다.

파편이 바닥에 떨어져 멈추면 잠들기 상태가 되는지도 확인합니다. 각 변경은 하나씩 적용하고, 같은 폭발 장면에서 언리얼 인사이트로 물리 CPU 시간을 다시 비교합니다.

3. ProfileGPU로 본 물리 비용

팀원이 ProfileGPU를 보고 "물리 비용이 크지 않다"고 말합니다. 그런데 Stat Unit에서는 게임 스레드의 시간이 프레임 예산을 넘고 있습니다. 팀원의 판단이 맞을까요?

해설 보기

맞지 않을 수 있습니다. ProfileGPU는 렌더링과 GPU 비용을 보는 도구라서, CPU에서 계산하는 카오스 강체 시뮬레이션의 시간은 보여 주지 않습니다.

게임 스레드의 시간이 예산을 넘는다면, 언리얼 인사이트로 같은 장면의 CPU 시간을 보며 물리 작업이 얼마나 차지하는지 확인해야 합니다. 그 결과를 보고 물리가 원인인지, 다른 CPU 작업이 원인인지 판단합니다.

카오스 물리의 기록과 시각화는 Epic의 카오스 비주얼 디버거 안내에서 확인할 수 있습니다.

이것으로 7장을 마칩니다. 7장에서는 물리 엔진의 기본 설정과 질량, 감쇠, 충돌 이벤트를 익히고, 중력과 충돌 응답을 조정하는 방법, 물리 재질로 표면마다 다른 반응을 만드는 방법, 캐릭터 무브먼트 컴포넌트로 캐릭터의 움직임을 구간마다 바꾸는 방법, 그리고 물리 시뮬레이션의 비용을 측정하며 줄이는 방법까지 레벨의 물리 환경을 다뤘습니다. 다음 장의 환경과 상호작용하는 오브젝트 설정부터는 플레이어가 문이나 장치와 상호작용하는 오브젝트를 만드는 데서 시작해, UI와 환경의 연동, 움직이는 오브젝트, 환경 변수에 따른 반응, 상호작용의 디버깅까지 환경 상호작용을 구현합니다.