게임 물리 엔진: 충돌 판정이 프레임을 지키는 설계법
캐릭터가 벽을 뚫거나 바닥 위에서 미세하게 떨리고, 오브젝트가 많아지는 순간 프레임이 급락한다면 문제는 물리 엔진 자체보다 충돌 판정의 범위와 실행 순서에 있을 가능성이 큽니다. 게임 물리 엔진 개발자 태윤에게 실제 프로젝트에서 충돌 시스템을 설계하고 병목을 찾는 방법을 물었습니다.
충돌 판정은 왜 오브젝트 수보다 빠르게 무거워질까
Q. 물체가 조금 늘었을 뿐인데 프레임이 크게 떨어지는 이유는 무엇인가요?
A. 가장 단순한 충돌 시스템은 모든 물체 쌍을 검사합니다. 물체가 100개라면 약 5천 쌍이지만 1,000개가 되면 약 50만 쌍까지 늘어납니다. 실제 충돌 여부와 무관하게 후보를 만드는 단계부터 비용이 폭증하는 구조이므로, 화면에 보이는 오브젝트 수만 보고 성능을 예상하면 판단을 그르치기 쉽습니다.
게임 물리 엔진은 보통 넓은 단계인 Broad Phase에서 가능성 없는 쌍을 제거하고, 좁은 단계인 Narrow Phase에서 형상 사이의 실제 접촉점을 계산합니다. 따라서 개발자가 먼저 확인할 값은 충돌 함수 한 번의 속도가 아니라 프레임마다 만들어지는 후보 쌍의 수입니다. 정지한 배경 물체와 움직이는 물체를 같은 방식으로 갱신하거나, 거대한 경계 상자 하나가 여러 공간 셀에 걸치면 후보가 예상보다 훨씬 많아집니다.
예를 들어 창고 장면에 상자 2,000개를 배치했지만 실제로 움직이는 상자가 30개뿐이라면, 정적·동적 그룹을 분리하는 것만으로 탐색량을 크게 줄일 수 있습니다. 반대로 폭발로 모든 상자가 동시에 깨어나는 장면에서는 평소 평균값이 아니라 최악 프레임의 후보 수를 기준으로 설계해야 합니다.
- 전체 물체 수: 장면 규모를 보여주지만 실제 연산량을 직접 설명하지는 않습니다.
- 활성 물체 수: 속도나 위치가 변해 경계 구조를 갱신해야 하는 대상을 뜻합니다.
- 후보 쌍 수: Narrow Phase와 접촉 해결 단계의 비용을 예측하는 핵심 지표입니다.
- 접촉점 수: 솔버 반복 횟수와 함께 CPU 시간을 좌우하므로 별도로 기록해야 합니다.
전문가 조언: 평균 60fps보다 먼저 최악의 한 프레임을 찾으십시오. 플레이어가 체감하는 끊김은 평균값이 아니라 폭발, 붕괴, 스폰이 겹친 순간에 만들어집니다.
공간 분할 방식은 장르와 움직임에서 결정된다
Q. 균일 그리드, 쿼드트리, BVH 중 무엇을 선택해야 하나요?
A. 모든 프로젝트에 우월한 자료구조는 없습니다. 탑다운 슈팅처럼 크기가 비슷한 유닛이 평평한 공간에 고르게 퍼진다면 균일 그리드가 구현과 갱신 모두 단순합니다. 넓은 월드에서 밀도가 지역마다 크게 다르면 쿼드트리나 옥트리가 유리할 수 있고, 크기와 이동 범위가 다양한 3D 물체에는 동적 AABB 트리나 BVH가 안정적인 선택이 됩니다.
선택할 때는 검색 속도뿐 아니라 업데이트 비용을 봐야 합니다. 빠르게 움직이는 물체가 노드 경계를 자주 넘으면 트리 재삽입이 늘어나고, 크기가 제각각인 물체를 작은 그리드 셀에 넣으면 하나의 대형 물체가 수십 개 셀을 점유합니다. 독자의 게임에 자동차와 건물이 함께 등장합니까? 그렇다면 하나의 구조에 전부 밀어 넣기보다 정적 월드용 BVH와 동적 차량용 그리드를 조합하는 편이 실용적입니다.
초기 설계 회의에서는 기술 이름보다 플레이 패턴을 먼저 적어야 합니다. 장면당 최대 개체 수, 한 프레임에 이동하는 비율, 오브젝트 크기 편차, 순간 생성량을 수치로 합의해 두십시오. 개발 행사에서 다양한 엔진 사례를 접할 때 참고할 수 있는 GDC의 의미와 역할도 알아두면 발표 자료를 프로젝트 조건에 맞게 해석하는 데 도움이 됩니다.
| 방식 | 잘 맞는 상황 | 주의할 점 |
|---|---|---|
| 균일 그리드 | 비슷한 크기의 다수 유닛 | 대형 물체와 밀도 편차 |
| 쿼드트리·옥트리 | 지역별 밀도가 다른 월드 | 경계 이동과 트리 깊이 |
| 동적 AABB 트리 | 크기와 이동이 다양한 물체 | 재삽입 및 균형 조정 비용 |
| 정적 BVH | 변하지 않는 지형과 건물 | 런타임 변경에 불리함 |
- 프로토타입에서 후보 쌍의 평균값과 상위 1% 값을 함께 측정합니다.
- 정적 물체, 동적 물체, 트리거를 서로 다른 레이어로 나눕니다.
- 셀 크기나 트리 여유 경계값을 상수로 고정하지 말고 장면 데이터로 검증합니다.
고속 이동과 떨림은 시간 처리부터 의심해야 한다
Q. 총알이 얇은 벽을 통과하는 현상은 어떻게 막나요?
A. 일반적인 이산 충돌 판정은 이전 위치와 현재 위치에서만 형상을 검사합니다. 총알이 한 프레임 동안 자신의 길이보다 먼 거리를 이동하면 두 위치 사이에 있던 벽을 건너뛸 수 있습니다. 이를 터널링이라고 하며, 프레임레이트가 내려갈수록 이동 거리가 커지기 때문에 재현 빈도도 높아집니다.
모든 물체에 연속 충돌 판정인 CCD를 켜면 안전해 보이지만 계산량과 예외 처리가 크게 늘어납니다. 총알, 빠른 차량, 플레이어처럼 실패 비용이 큰 객체만 선별하고 나머지는 이산 판정을 유지하는 편이 낫습니다. 광선이나 형상 캐스트로 이동 구간을 먼저 검사하는 방식도 유용하지만, 회전하는 긴 물체나 복잡한 볼록 형상에는 별도 검증이 필요합니다.
Q. 바닥에 선 캐릭터가 떨리는 문제도 같은 원인인가요?
A. 일부는 시간 간격 문제이고 일부는 솔버와 캐릭터 제어 방식의 충돌입니다. 렌더링 프레임의 가변 델타를 그대로 물리에 넣으면 동일한 상황에서도 결과가 달라지고, 접촉 보정량이 프레임마다 흔들릴 수 있습니다. 고정 시간 간격으로 물리를 실행하고 렌더링 위치는 보간하되, 한 프레임에 허용할 최대 서브스텝 수를 제한해야 과부하가 연쇄적으로 커지는 현상을 막을 수 있습니다.
- 물리 시뮬레이션을 60Hz 또는 게임에 맞는 고정 주기로 분리합니다.
- 누적 시간이 커져도 한 프레임의 최대 반복 횟수를 제한합니다.
- 고속 객체에만 CCD나 스윕 테스트를 적용합니다.
- 접촉 오프셋, 관통 보정률, 정지 임계값을 한 번에 하나씩 조정합니다.
- 카메라 보간 문제와 실제 물리 떨림을 디버그 도형으로 구분합니다.
고정 스텝은 정확성을 자동으로 보장하는 버튼이 아닙니다. 입력 적용 시점, 보간 대상, 과부하 때 버릴 시간의 정책까지 하나의 시스템으로 설계해야 합니다.
프로파일링은 함수 시간이 아니라 장면의 원인을 추적한다
Q. 물리 스레드가 느릴 때 어떤 순서로 조사해야 하나요?
A. 먼저 Broad Phase, Narrow Phase, 접촉 생성, 솔버, 콜백 시간을 분리해서 봅니다. 물리 전체가 8ms라는 숫자만으로는 해결책을 정할 수 없습니다. 후보 쌍이 폭증한 것인지, 복잡한 메시 충돌이 반복되는지, 접촉 콜백 안에서 게임 로직이 무거운 작업을 하는지에 따라 처방이 완전히 달라집니다.
특히 충돌 콜백은 물리 비용으로 집계되면서 실제 원인이 숨기 쉽습니다. 접촉할 때마다 이펙트를 즉시 생성하고 오디오 리소스를 찾거나, 컴포넌트 계층을 반복 검색하면 단순한 충돌이 비싼 이벤트가 됩니다. 콜백에서는 필요한 식별자와 접촉 정보만 큐에 기록하고, 후속 게임 로직은 안전한 단계에서 일괄 처리하는 구조가 좋습니다.
성능 개선에도 예산 우선순위가 필요합니다. 모든 장면을 무조건 최적화하기보다 하위 사양 목표, 동시 접촉 최대치, 허용 CPU 시간처럼 측정 가능한 기준을 잡아야 합니다. 자원을 목표별로 배분하는 관점은 계획예산 제도의 개념과도 닿아 있습니다. 게임 개발에서는 이를 프레임 예산과 기능 우선순위에 적용할 수 있습니다.
- 1단계: 물리 단계별 CPU 시간과 호출 횟수를 캡처합니다.
- 2단계: 후보 쌍, 실제 접촉 쌍, 접촉점 수를 같은 프레임에서 기록합니다.
- 3단계: 비용이 큰 충돌 레이어와 형상 유형을 색상별로 시각화합니다.
- 4단계: 폭발이나 대량 스폰 등 재현 가능한 스트레스 장면을 저장합니다.
- 5단계: 최적화 전후의 중앙값뿐 아니라 상위 1% 프레임 시간을 비교합니다.
예컨대 솔버 시간이 높다고 반복 횟수부터 줄이면 관절이 늘어나거나 오브젝트가 겹칠 수 있습니다. 먼저 장식용 파편끼리 충돌할 필요가 있는지, 잠든 물체를 불필요하게 깨우는 이벤트가 있는지 살펴보십시오. 계산을 빠르게 만드는 것보다 계산하지 않아도 되는 규칙을 찾는 편이 더 큰 개선을 만드는 경우가 많습니다.
엔진 업데이트와 콘텐츠 확장이 바꾸는 물리 기준
Q. 출시 이후에도 충돌 설계를 계속 검증해야 하나요?
A. 그렇습니다. 물리 엔진 버전이 바뀌면 접촉 오프셋의 기본값, 슬리핑 조건, CCD 처리, 멀티스레딩 스케줄이 달라질 수 있습니다. 같은 설정 파일을 사용해도 미세한 동작이나 성능이 같다고 단정할 수 없으므로, 엔진 업데이트 전후에 대표 장면을 자동 재생하고 결과를 비교해야 합니다.
콘텐츠 확장도 기준을 바꿉니다. 출시 시점에는 최대 50명이던 전투가 업데이트 후 200명으로 늘거나, 파괴 가능한 건물이 추가되면 정적 구조를 전제로 한 최적화가 무너집니다. 기획 단계에서 물리 비용을 공유하려면 담당자의 역할과 의사결정 범위를 분명히 해야 하며, 게임 기획자의 역할 설명을 참고해 기술 제약을 콘텐츠 규칙으로 번역하는 협업 방식을 세울 수 있습니다.
Q. 회귀 테스트에는 어떤 데이터를 남겨야 하나요?
A. 단순히 캐릭터가 벽을 통과했는지만 검사하지 말고 성능과 동작을 함께 저장하십시오. 동일한 입력 시퀀스, 엔진 버전, 물리 설정, 평균·상위 1% 프레임 시간, 후보 쌍과 접촉점 수를 빌드별로 남기면 변화의 원인을 좁힐 수 있습니다. 완전한 비트 단위 결정성이 어렵다면 위치 오차나 완료 시간처럼 프로젝트가 허용할 범위를 정의하는 방식도 현실적입니다.
- 엔진 업그레이드 전 대표 전투, 차량, 붕괴 장면의 기준 캡처를 보관합니다.
- 충돌 레이어 표와 예외 규칙을 코드 변경 내역과 함께 버전 관리합니다.
- 신규 캐릭터나 대형 보스가 추가될 때 경계 크기와 후보 쌍 증가량을 측정합니다.
- CPU 코어 수가 다른 최소·권장 사양 장치에서 같은 테스트를 반복합니다.
- 물리 미들웨어의 릴리스 노트에서 기본값 변경과 알려진 문제를 확인합니다.
앞으로 병렬 솔버와 GPU 물리 지원이 확대되더라도 실제 이득은 엔진 버전, 하드웨어 구성, 전송 비용에 따라 달라질 수 있습니다. 그러므로 특정 설정을 영구적인 정답으로 문서화하기보다 어떤 장면과 수치에서 채택했는지를 함께 기록하십시오. 시간이 지나 콘텐츠 규모나 미들웨어 구현이 변하면 그 근거부터 다시 측정하는 것이 가장 안전한 유지보수 전략입니다.

- 다음글게임 버전 관리, Git LFS와 Perforce 사이의 선택 26.09.08
등록된 댓글이 없습니다.
