게임 물리학
게임의 물리는 현실을 그대로 옮긴 것이 아니라, 1/60초마다 미분 방정식을 근사하며 그럴듯함과 안정성 사이에서 고른 결과다. 적분법과 시간 간격에서 시작해 입자, 투사체, 강체와 충돌 응답, 3D 회전, 관절과 솔버, 물리 엔진의 구조를 지나 차량, 비행기, 배, 총탄과 폭발, 스포츠, 휴대폰 센서까지 직접 계산한 그림으로 따라간다.
목차 (16)
이 노트는 운동을 시뮬레이션하는 법에 집중한다. 힘과 에너지, 운동량 같은 물리 원리 자체는 물리학 노트, 벡터·행렬·쿼터니언과 충돌 판정의 수학은 게임 개발 수학 노트, 히트박스·래그돌·보로노이 파괴·레이캐스트 서스펜션 같은 제작 기법은 게임 개발 › 물리·판정 노트에 있다. 강체를 넘어 천, 머리카락, 연체, 유체를 다루는 방법은 유체·천·연체 시뮬레이션 노트로 이어진다.
게임 물리 루프, 단위, 운동 방정식
게임 물리는 매 걸음 같은 일을 되풀이한다. 물체마다 걸린 힘을 모두 더해 가속도를 구하고(a = F/m), 가속도로 속도를, 속도로 위치를 조금 옮긴 뒤, 겹친 물체를 찾아 밀어내고 튕긴다. 운동학(위치·속도·가속도의 관계)과 동역학(힘이 운동을 바꾸는 법칙)이 각각 이 고리의 앞과 뒤를 맡는다. 등가속도라면 x = x₀ + v₀t + ½at²라는 닫힌 식이 있어서 정지 상태에서 1초 동안 떨어진 거리는 4.91m다. 하지만 힘이 속도나 위치에 따라 바뀌는 순간(항력, 스프링, 충돌) 닫힌 식은 사라지고, 짧은 시간 간격 dt로 잘라 한 걸음씩 근사하는 수밖에 없다.
- 단위를 정한다: 1 단위를 1m, 질량을 kg, 시간을 초로 두면 중력 9.81m/s², 공기 밀도 1.225kg/m³ 같은 현실 값을 그대로 쓸 수 있다. 2D 게임은 픽셀을 그대로 쓰기 쉬운데, 그러면 중력이 "980픽셀/초²"처럼 감으로 정한 숫자가 된다. Box2D 문서가 픽셀 대신 미터·킬로그램·초 단위를 쓰고 움직이는 물체를 0.1~10m 크기로 두라고 권하는 것도 엔진의 허용 오차가 그 크기에 맞춰져 있기 때문이다.
- 좌표계를 정한다: 위가 +y인지 +z인지, 오른손 좌표계인지, 회전의 양의 방향이 어느 쪽인지를 처음에 못 박는다. 화면 좌표(아래가 +y)와 물리 좌표(위가 +y)를 섞으면 중력 부호가 뒤집히는 버그가 흔하다. 좌표계와 손 방향은 게임 개발 수학 노트에 그림으로 있다.
- 상태와 입력을 나눈다: 물체의 상태는 위치·속도(회전하면 방향·각속도까지)이고, 힘과 충격량은 그 상태를 바꾸는 입력이다. 저장·되감기·네트워크 동기화를 할 때 상태만 복사하면 되도록 둘을 섞지 않는다.
고정 시간 간격(누산기에 흐른 시간을 쌓아 고정 dt로 덜어 쓰는 방식)과 보간은 게임 개발 수학 노트의 "물리 적분과 고정 시간 간격" 절과 엔진 구조 노트에 그림과 함께 있다. 여기서는 그 걸음 안에서 무엇을 계산하는지를 본다.
수치 적분 네 가지와 에너지 드리프트
"속도로 위치를 옮긴다"는 한 줄에도 방법이 여럿이다. 명시적 오일러, 반암시적 오일러, 베를레의 기본 생각은 게임 개발 › 물리 노트의 적분 절에 있으니, 여기서는 네 방법을 같은 용수철에 걸어 에너지가 어떻게 새는지 나란히 놓는다. 마찰이 없는 용수철은 에너지가 일정해야 하므로, 처음 에너지와의 비가 1에서 얼마나 벗어나는지가 곧 적분 오차의 크기다.
| 방법 | 걸음당 힘 계산 | 정확도(전역 오차) | 에너지 | 게임에서 |
|---|---|---|---|---|
| 명시적 오일러 | 1번 | 1차(dt에 비례) | 진동계에서 계속 불어난다 | 설명용. 실제로는 피한다 |
| 반암시적 오일러 | 1번 | 1차 | 오르내리지만 쌓이지 않는다(심플렉틱) | 대부분의 강체 엔진 기본 |
| 속도 베를레 | 1번 | 2차(dt²) | 오르내림이 더 작다(심플렉틱) | 천·밧줄·입자, 위치 기반 동역학 |
| RK4 | 4번 | 4차(dt⁴) | 아주 천천히 줄어든다(3초에 0.010%) | 궤도·매끄러운 힘. 충돌이 많으면 이득이 줄어든다 |
표의 "심플렉틱"은 위치와 속도가 이루는 상태 공간의 넓이를 보존하는 성질이다. 이런 방법은 에너지를 정확히 지키지는 못해도 진짜 에너지에 가까운 어떤 값을 지켜서, 오래 돌려도 진폭이 한쪽으로 흐르지 않는다. RK4는 한 걸음은 훨씬 정확하지만 심플렉틱이 아니어서 아주 긴 시간에는 에너지가 조금씩 빠져나간다. 게임에서 이 차이보다 더 큰 문제는 뻣뻣함(stiffness)이다. 아주 센 스프링은 주기가 dt보다 짧아져 어느 명시적 방법으로도 터진다. 이때는 dt를 줄이거나, 다음 상태의 힘을 쓰는 암시적 방법이나 뒤에 나올 소프트 제약으로 바꾼다. 게임 쪽에서 본 적분법과 안정성은 Erin Catto의 GDC 2015 발표 Numerical Methods가 다룬다.
입자 시스템
불꽃, 연기, 물보라, 파편처럼 수가 많고 서로 부딪치지 않아도 되는 것은 입자로 다룬다. 입자는 크기도 회전도 없는 점이라 상태가 위치·속도·나이뿐이고, 질량 중심이나 관성 모멘트를 따질 필요가 없다. 그래서 수천~수십만 개를 한꺼번에 돌릴 수 있고, GPU의 계산 셰이더로 옮기기도 쉽다.
- 분출기(emitter): 초당 몇 개를, 어디서, 어떤 방향·속도 분포로 내보낼지 정한다. 같은 씨앗(seed)의 의사 난수를 쓰면 매번 같은 모양이 나와 다시 보기와 디버깅이 쉽다.
- 힘: 중력, 속도에 비례하는 항력(연기는 금방 느려진다), 바람장, 소용돌이처럼 위치마다 값을 주는 힘장(force field)을 더한다. 입자끼리 끌거나 미는 힘을 넣으면 쌍마다 계산해야 해서 비용이 갑자기 커진다.
- 땅과 부딪치기: 땅 높이보다 내려간 입자를 표면으로 되돌리고, 법선 방향 속도를 반발 계수만큼 뒤집고, 접선 속도를 마찰로 줄인다. 깊이 버퍼나 높이장으로 대충 판정하는 경우가 많다.
- 수명과 재사용: 나이가 수명을 넘으면 지운다. 매번 새로 만들고 버리지 않고 정해진 크기의 배열을 돌려 쓰는 것이 보통이다(엔진 구조 노트의 오브젝트 풀).
입자 몇 개를 거리 제약으로 묶으면 천과 밧줄이 되고, 입자 사이의 압력과 점성을 계산하면 SPH 같은 유체가 된다. 화면에서 입자를 어떻게 그려 효과를 내는지는 게임 개발 › 효과 노트에 있다.
투사체: 중력, 항력, 바람, 마그누스
진공이라면 투사체는 포물선을 그리고, 같은 높이로 떨어지는 거리는 v²·sin2θ/g다. 공기 속에서는 두 힘이 더해진다. 항력은 공기에 대한 속도의 반대쪽으로 D = Cd·½ρv²·A만큼 걸리고, 회전하는 공에는 속도에 수직인 마그누스 힘이 생긴다. 두 힘 모두 땅이 아니라 공기에 대한 속도로 계산해야 바람이 자연스럽게 들어간다. 맞바람이면 공기에 대한 속도가 커져 항력이 세진다.
- 항력은 속도의 제곱: 빠를수록 급격히 세져서, 실제 궤적은 내려올 때가 올라갈 때보다 가파른 비대칭 모양이다. 질량이 같아도 단면적이 크면 더 빨리 느려지고, 크기가 같아도 무거우면 덜 느려진다(감속 = 힘 ÷ 질량).
- 마그누스 힘: 공이 돌면 한쪽 표면은 공기 흐름과 같은 방향으로, 반대쪽은 거슬러 움직여 둘레의 흐름이 한쪽으로 휜다. 공은 그 반작용으로 옆(역회전이면 위)으로 밀린다. 크기는 보통 ½ρv²A에 회전 정도에 따라 정해지는 양력 계수 CL을 곱해 나타낸다.
- 닫힌 식이 없다: 항력과 마그누스가 들어가면 궤적은 적분으로만 구한다. 조준선 예측을 그리려면 같은 적분을 미래로 미리 돌려야 한다. 그 기법과 프레임 경계 처리, 물속 항력의 함정은 게임 개발 › 물리 노트에 있다.
2D 강체: 질량 중심과 관성 모멘트
강체(rigid body)는 모양이 변하지 않는 물체다. 2D 강체의 상태는 질량 중심의 위치·속도에, 회전각 θ와 각속도 ω 하나씩이 더해진 것이다. 직선 운동에서 F = m·a이듯 회전에서는 토크 τ = I·α(각가속도)가 성립하고, 질량 m 자리에 관성 모멘트 I가 들어간다. 질량 중심에서 r만큼 떨어진 점에 힘 F를 주면 질량 중심은 F/m로 가속하고, 동시에 τ = r × F(2D에서는 rxFy − ryFx, 숫자 하나)만큼 돌기 시작한다.
질량 중심은 질량의 가중 평균 자리다(Σmixi ÷ Σmi). 모양이 고르면 도형의 무게 중심과 같다. 여러 도형을 붙인 물체는 각 도형의 질량 중심을 질량으로 가중 평균하고, 관성 모멘트는 각 도형의 값에 평행축 정리(I = I중심 + m·d²)로 옮긴 값을 더한다. 엔진은 충돌 도형과 밀도를 받아 이 계산을 대신 해 준다.
시뮬레이션은 직선 운동과 회전을 나란히 적분한다. v += (F/m)·dt, ω += (τ/I)·dt, x += v·dt, θ += ω·dt. 계산에는 m과 I보다 그 역수 1/m과 1/I를 저장해 두는 쪽이 편하다. 움직이지 않는 벽이나 땅은 역수를 0으로 두면 "질량이 무한대"가 되어, 같은 공식으로 아무리 큰 충격량을 받아도 움직이지 않는다. 회전을 막고 싶은 캐릭터는 1/I만 0으로 두면 된다.
충돌 검출에서 충돌 응답까지
충돌 검출은 "닿았나, 어디서, 어느 방향으로, 얼마나 깊이"를 구하는 기하 문제다. AABB와 원, 분리축 정리(SAT), 넓은 단계와 좁은 단계, 빠른 물체의 터널링을 막는 스윕 판정은 게임 개발 수학 노트와 게임 개발 › 물리 노트에 있다. 검출 결과로 접점, 법선 n, 파고든 깊이가 나오면, 충돌 응답은 그걸로 속도를 바꾸는 물리 문제다.
현실의 충돌은 아주 짧은 시간 동안 아주 큰 힘이 오가는 일이다. 게임은 그 과정을 건너뛰고 속도를 한 번에 바꾸는 충격량(impulse, j, 단위 N·s) 하나로 바꿔 쓴다. 조건은 둘이다. 접점에서 법선 방향 상대 속도가 충돌 뒤 −e배가 될 것(e는 반발 계수, 0이면 달라붙고 1이면 에너지를 잃지 않는다), 그리고 두 물체가 크기는 같고 방향은 반대인 충격량을 받을 것(운동량 보존). 이 둘을 풀면 아래 그림 왼쪽의 공식이 나온다.
- 멀어지는 중이면 하지 않는다: 법선 방향 상대 속도가 이미 0 이상이면 충격량을 주지 않는다. 이걸 빼먹으면 겹친 채 몇 프레임 동안 서로 끌어당기는 버그가 생긴다.
- 마찰 충격량: 접선 방향 t로도 같은 꼴의 충격량 jt를 구해 미끄러지는 속도를 0으로 만들려 한다. 다만 쿨롱 마찰 법칙에 따라 |jt| ≤ μ·jn로 자른다. 잘리지 않으면 붙어 있는(정지 마찰) 것이고, 잘리면 미끄러지는 것이다. 정지·운동 마찰 계수를 나누는 엔진도 있지만 하나로 쓰는 경우가 많다.
- 파고든 깊이는 따로 지운다: 충격량은 속도만 바꾸므로 이미 겹친 깊이는 남는다. 깊이에 비례하는 작은 속도를 더하거나(바움가르테 안정화), 위치를 직접 조금씩 밀어내는(위치 보정) 방법을 쓴다. 너무 세게 밀면 쌓인 상자가 떨린다.
- 작은 속도에서는 e를 끈다: 거의 멈춘 물체에도 반발을 주면 바닥에서 끝없이 잘게 튄다. 상대 속도가 어떤 문턱 아래면 e를 0으로 보는 것이 보통이다.
3D 회전: 관성 텐서, 각속도, 쿼터니언
3D에서는 회전이 숫자 하나로 끝나지 않는다. 각속도 ω는 회전축 방향을 가리키고 길이가 초당 회전량(rad/s)인 벡터이고, 관성 모멘트는 3×3 행렬인 관성 텐서 I가 된다. 같은 물체라도 어느 축으로 돌리느냐에 따라 돌리기 어려운 정도가 다르기 때문이다. 물체에 붙은 주축으로 보면 I는 대각 행렬(세 주축 관성 모멘트)이고, 월드 좌표에서는 물체의 회전 행렬 R로 I월드 = R·I몸·RT로 매 걸음 다시 구한다. 역행렬도 같은 식으로 옮기면 되므로 몸 좌표의 역관성 텐서를 한 번만 계산해 둔다.
- 각운동량 L = I·ω: 토크가 없으면 보존되는 것은 ω가 아니라 L이다. 그래서 길쭉한 물체를 비스듬히 던지면 ω의 방향이 저절로 흔들린다. 이것을 제대로 내려면 각속도 갱신에 자이로 항 ω × (I·ω)를 넣어야 하고, 이 항이 세 주축 관성 모멘트가 모두 다른 물체에서 중간 축 회전이 불안정해지는 현상(테니스 라켓 정리)을 만든다. 게임에서는 이 항이 수치적으로 불안정해 빼거나 암시적으로 처리하는 엔진도 있다.
- 방향은 쿼터니언으로: 오일러 각은 짐벌 락이 있고, 회전 행렬은 적분하면 직교성이 깨진다. 단위 쿼터니언 q는 값 넷으로 방향을 담고, 각속도로 dq/dt = ½·ω·q(ω를 실수부 0인 쿼터니언으로 본 곱)로 적분한다. 쿼터니언의 정의와 slerp는 게임 개발 수학 노트에 있다.
정규화는 오차를 숨기는 땜질이 아니라 꼭 필요한 단계다. 위 적분은 쿼터니언을 접선 방향으로 한 걸음 옮기는 것이라 늘 단위 구 바깥으로 조금 나간다. 각속도가 아주 빠른 물체(바퀴, 프로펠러)는 정규화를 해도 방향 오차가 커지므로, 회전량 ω·dt만큼의 회전 쿼터니언을 직접 만들어 곱하는 방식이 더 정확하다.
스프링, 댐퍼, 제약 조건
물체를 서로 이으면 두 방법이 있다. 하나는 스프링–댐퍼로 힘을 주는 것이다. 늘어난 길이 x에 비례해 당기고(−k·x), 늘어나는 속도에 비례해 버틴다(−c·v). 감쇠 계수 c가 임계값 2√(k·m)과 같으면 넘치지 않고 가장 빨리 제자리로 돌아온다. 예를 들어 무게 1300kg 차의 바퀴 하나가 받치는 몫(4분의 1)에 강성 30kN/m 스프링을 달면 임계 감쇠는 약 6.2kN·s/m이다. 실제 서스펜션은 승차감 때문에 이보다 작게(감쇠비 0.2~0.4 근처) 잡는 경우가 많다.
다른 하나는 제약 조건(constraint)이다. "두 점 사이 거리는 1m", "이 두 물체는 이 점에서 붙어 있고 한 축으로만 돈다"처럼 지켜야 할 식 C = 0을 주고, 그 식을 지키는 데 필요한 만큼만 충격량을 계산한다. 공(볼) 관절, 경첩(힌지), 미끄럼(슬라이더), 거리 관절, 그리고 앞 절의 접촉과 마찰도 모두 같은 틀의 제약이다. 아주 센 스프링을 쓰면 앞 절에서 본 뻣뻣함 때문에 터지지만, 제약은 처음부터 "늘어나지 않음"을 풀기 때문에 안정적이다. 반대로 제약을 조금 무르게 만들어 스프링처럼 쓰는 것이 소프트 제약이다.
제약이 여러 개 얽히면(사슬, 래그돌, 쌓인 상자) 모든 식을 한 번에 푸는 대신 반복 솔버로 하나씩 차례로 맞추기를 몇 번 되풀이한다. Erin Catto가 GDC 2006에서 정리한 순차 충격량(sequential impulses)이 대표적이고, 수학적으로는 가우스–자이델 반복이다. 접촉마다 쌓인 충격량을 다음 걸음의 출발값으로 다시 쓰는 웜 스타트(warm start)가 수렴을 크게 돕는다. 위치를 직접 옮기는 위치 기반 동역학(PBD)도 같은 반복을 위치에 대고 한다.
시작: 막대 4개가 모두 1.5배로 늘어나 사슬이 2.00m 길다. 왼쪽 흐린 점이 맞는 길이다.
위 사슬은 4번 반복하면 아직 0.91m, 16번 반복하면 0.14m 늘어나 있다. 반복이 모자라면 긴 사슬과 높이 쌓은 탑이 늘어지고 흔들린다. 무거운 물체가 가벼운 물체 위에 매달릴 때 특히 심하다(질량비 문제). 그래서 엔진은 반복 수를 설정으로 열어 두고, 래그돌처럼 관절이 긴 사슬에는 관절을 한꺼번에 푸는 다른 방법을 쓰기도 한다. 래그돌의 구성은 게임 개발 › 물리 노트에 있다.
물리 엔진의 구조
물리 엔진은 지금까지의 조각을 한 걸음 안에 일정한 순서로 묶은 것이다. 엔진마다 이름과 순서가 조금씩 다르지만 큰 줄기는 비슷하다.
- 몸체·도형·재질을 나눈다: 강체(질량·속도), 그에 붙은 충돌 도형(구, 상자, 캡슐, 볼록 껍질, 삼각형 메시), 재질(마찰·반발)을 따로 둔다. 도형 하나를 여러 몸체가 같이 쓰고, 한 몸체가 도형 여러 개를 가질 수 있다.
- 정적·운동학·동적: 움직이지 않는 지형(정적), 코드가 직접 움직이고 힘에는 반응하지 않는 발판·문(운동학, kinematic), 힘과 충돌로 움직이는 물체(동적)를 구분한다. 운동학 물체는 동적 물체를 밀지만 밀리지 않는다.
- 섬과 잠재우기: 서로 닿거나 관절로 이어진 물체 묶음(섬)을 나눠, 묶음 전체가 한동안 거의 움직이지 않으면 계산에서 뺀다(sleep). 큰 장면의 비용 대부분을 여기서 아낀다. 섬은 서로 독립이라 여러 스레드로 나눠 풀기에도 좋다.
- 쿼리: 레이캐스트, 도형 스윕, 겹침 검사처럼 시뮬레이션과 별개로 "여기 뭐가 있나"를 묻는 기능. 총알 판정, 땅 감지, 시야 검사가 모두 이것을 쓴다.
- 결정성: 같은 입력에서 같은 결과가 나오는지는 엔진·설정·플랫폼에 따라 다르다. 멀티플레이 동기화나 리플레이에 기대려면 문서를 보고 확인해야 한다.
널리 알려진 이름으로는 2D의 Box2D(Erin Catto), 3D의 Bullet, NVIDIA의 PhysX, 다중 코어 성능을 내세운 Jolt가 있다. 상용 엔진(Unity, Unreal, Godot)은 이들 중 하나를 쓰거나 자체 물리를 갖추는데, 어떤 엔진의 어느 버전이 무엇을 쓰는지는 자주 바뀌므로 해당 엔진 문서에서 확인한다. 엔진을 고르는 기준은 엔진 구조 노트에 있다.
차량과 호버크래프트
자동차 모델은 엔진에서 바퀴까지 토크가 흘러가는 길을 따라 짠다. 엔진은 회전수(rpm)마다 낼 수 있는 토크가 정해진 곡선을 갖고, 변속기와 종감속 기어가 회전을 줄이는 만큼 토크를 키운다. 바퀴 반지름 r로 나누면 바퀴가 땅을 미는 힘이 된다. 힘 = 엔진 토크 × 기어비 × 종감속비 × 효율 ÷ r, 차 속도 = 엔진 각속도 × r ÷ (기어비 × 종감속비)다.
- 타이어가 힘의 끝: 위 힘은 "낼 수 있는" 힘이다. 실제로 땅에 전해지는 힘은 바퀴가 받는 하중 × 마찰의 한계를 넘지 못하고, 넘으면 바퀴가 헛돈다. 1단 최대 구동력은 이 차 무게의 0.68배라 마찰 계수가 그보다 낮은 젖은 길에서는 휠스핀이 난다.
- 슬립: 타이어 힘은 바퀴가 미끄러지는 정도(슬립 비, 슬립 각)의 함수로 계산한다. 슬립이 조금 있을 때 힘이 가장 크고, 더 미끄러지면 오히려 준다. 슬립 곡선과 레이캐스트 서스펜션, 구동 방식에 따른 오버·언더스티어는 게임 개발 › 물리 노트에서 다룬다.
- 저항: 공기 저항(½ρCdAv², 고속에서 지배적)과 구름 저항(하중에 비례, 저속에서 지배적)이 구동력과 맞선다. 차 무게 이동(가속 때 뒤로, 제동 때 앞으로)이 바퀴별 하중을 바꿔 그립도 바꾼다.
호버크래프트는 바퀴 대신 바닥 밑에 공기를 불어 넣은 쿠션에 떠 있다. 쿠션 압력 × 바닥 면적이 무게와 같아지면 뜨므로, 300kg짜리를 6m² 쿠션에 띄우는 데 필요한 압력은 491Pa로 대기압의 0.5% 남짓이다. 땅과의 마찰이 거의 없어서 추진 프로펠러로 밀고 방향타로 꺾어도 차처럼 옆 그립이 생기지 않는다. 그래서 게임 속 호버크래프트는 몸이 돌아가도 원래 가던 쪽으로 미끄러지는(관성 드리프트) 느낌이 특징이다. 모델링은 쿠션을 바닥 몇 점의 스프링–댐퍼 레이캐스트로 흉내 내고, 약한 옆 항력만 주는 식으로 한다.
비행기와 배: 공기와 물이 주는 힘
비행기
날고 있는 비행기에는 네 힘이 걸린다. 위로 양력, 아래로 무게, 앞으로 추력, 뒤로 항력. 양력과 항력은 같은 꼴의 식 C·½ρv²·S로 쓰고(S는 날개 면적), 계수 CL은 날개가 흐름을 받는 각도인 받음각 α에 따라 바뀐다. 받음각이 커지면 양력이 거의 비례해 늘다가, 어느 각을 넘으면 날개 윗면의 흐름이 떨어져 나가며 양력이 갑자기 준다. 이것이 실속(stall)이다.
실속 속도는 양력이 무게와 같아지는 가장 느린 속도 √(2mg ÷ (ρ·S·CLmax))다. 무게 1,100kg, 날개 16.2m², CLmax 1.6을 넣으면 26.1m/s(약 94km/h)로, 소형 4인승 비행기와 비슷한 크기다. 게임에서 비행 모델을 짜는 흔한 방법은 날개, 꼬리 날개, 방향타를 각각 작은 날개 조각으로 보고, 조각마다 자기 위치의 공기 속도와 받음각으로 양력·항력을 구해 그 자리에 힘으로 주는 것이다. 그러면 승강타·보조 날개·방향타가 만드는 회전과 실속 때의 기수 떨어짐이 따로 짜지 않아도 저절로 나온다. 아케이드 비행 게임은 여기에 자세를 되돌리는 보정 토크를 더해 쉽게 만든다.
배
배는 부력으로 뜬다. 물에 잠긴 부피만큼의 물 무게가 위로 미는 힘(아르키메데스 원리)이고, 부력과 무게가 같아지는 깊이까지 잠긴다. 고른 상자라면 잠기는 깊이는 높이 × (물체 밀도 ÷ 물 밀도)다.
- 부력은 점마다 준다: 배 전체에 부력 하나를 주면 기울어도 되돌아오지 않는다. 선체를 작은 칸(점, 상자, 삼각형)으로 나눠 칸마다 잠긴 부피만큼의 부력을 그 자리에 주면, 기울어진 쪽이 더 잠겨 더 세게 밀므로 되세우는 토크가 저절로 생긴다. 파도의 높이장을 읽어 칸마다 수면 높이를 다르게 하면 파도에 흔들리는 배가 된다. Erin Catto의 발표 자료 모음에 Game Programming Gems 6의 부력 예제 소스가 있다.
- 물의 저항: 물은 공기보다 약 800배 무거워 저항이 크다. 앞뒤로는 작고 옆으로는 큰 저항을 주면 배가 옆으로 미끄러지지 않고 선수 방향으로 나아간다. 느린 속도에서는 속도에 비례하는 항, 빠르면 제곱 항을 섞는다.
- 추진과 조타: 프로펠러 추력은 선미 수면 아래 한 점에 주고, 방향타는 물에 대한 속도에 비례하는 옆 힘을 선미에 줘 배를 돌린다. 그래서 배는 멈춰 있으면 방향타가 듣지 않는다.
총탄과 폭발
총탄은 투사체 절의 식을 그대로 따르되 속도가 아주 빠르다. 초속 수백 m의 탄은 수십 m 안에서는 거의 직선으로 날아 히트스캔(쏘는 순간 광선 하나로 판정)으로 근사해도 티가 나지 않지만, 거리가 멀어지면 낙차와 비행 시간이 생긴다. 저격총의 탄도를 살리는 게임은 탄을 실제 투사체로 날리고, 탄 모양에 따른 항력을 탄도 계수 하나로 묶어 쓴다. 판정 방식의 장단점과 서버 판정은 게임 개발 › 물리 노트에 있다.
- 반동: 쏘기 전 운동량이 0이므로 탄과 총의 운동량은 크기가 같고 방향이 반대다. 실제로는 총구에서 뿜어지는 화약 가스도 운동량을 가져가 반동이 더 크다. 게임은 이 물리값보다 조준점이 튀는 패턴(반동 패턴)과 카메라 흔들림으로 느낌을 만드는 경우가 많고, 그 조율은 게임 개발 › 조작감 노트와 이어진다.
- 폭발의 실제: 폭발은 공기 압력이 순간적으로 치솟는 충격파를 만들고, 그 세기는 거리에 따라 아주 빠르게 준다. 폭약 양이 다른 폭발은 거리를 폭약 질량의 세제곱근으로 나눈 환산 거리(Z = R ÷ W1/3, 홉킨슨–크란츠 법칙)가 같으면 압력이 비슷하다. 폭약이 8배면 같은 세기가 2배 먼 곳까지 간다.
- 게임의 근사: 반경 안의 물체를 겹침 쿼리로 찾고, 중심에서 물체 쪽으로 감쇠를 곱한 충격량을 준다. 벽 뒤를 가리려면 중심에서 레이를 쏴 막혔는지 보고, 물체가 위로 날아가는 그림을 원하면 방향에 위쪽 성분을 조금 섞는다. 충격량을 질량 중심이 아닌 가까운 표면점에 주면 회전도 함께 생긴다. 맞은 물체가 부서지는 표현은 게임 개발 › 물리 노트의 보로노이 파괴가 맡는다.
스포츠: 회전하는 공과 당구
스포츠 게임의 공은 투사체 절의 항력과 마그누스 힘, 충돌 절의 반발과 마찰이 모두 드러나는 곳이다. 같은 식이라도 공마다 계수가 달라 느낌이 갈린다.
- 골프: 공 표면의 딤플은 공 둘레의 얇은 공기층(경계층)을 일부러 흐트러뜨려, 흐름이 공 뒤쪽까지 붙어 있게 만든다. 그러면 공 뒤에 생기는 낮은 압력 영역이 좁아져 항력이 크게 준다. 드라이버 샷의 강한 역회전은 마그누스 양력으로 공을 띄워 오래 날게 한다. 잔디에 떨어진 뒤 구르는 거리는 착지 각도와 남은 회전, 잔디 마찰로 정해진다.
- 야구: 투구의 회전축 방향이 마그누스 힘의 방향을 정한다. 역회전이 강한 빠른 공은 중력만 받을 때보다 덜 떨어지고, 전진 회전이 걸린 커브는 더 떨어진다. 회전이 거의 없는 너클볼은 실밥의 비대칭이 흐름을 흔들어 예측하기 어렵게 움직인다. 공의 실측 궤적과 계산기는 The Physics of Baseball에 있다.
- 튀는 공: 공이 바닥에 닿을 때 법선 쪽은 반발 계수, 접선 쪽은 마찰 충격량이 정한다. 역회전 걸린 공이 튀며 뒤로 감기고, 전진 회전 걸린 공이 튀며 앞으로 뻗는 것은 접점의 마찰이 회전을 직선 속도로 바꾸기 때문이다. 충돌 응답 공식에 회전 항을 넣으면 이 효과가 그대로 나온다.
당구는 충돌 응답의 교과서다. 충격량은 접점의 법선, 곧 두 중심을 잇는 선 방향으로만 오가므로 적구는 그 방향으로 출발하고, 질량이 같고 에너지가 보존되면 두 속도 벡터는 서로 수직이 된다. 실제 당구는 여기에 공이 천 위에서 미끄러지다 구르기 시작하는 과정, 수구에 준 위아래 회전(밀어치기, 끌어치기)과 옆 회전이 천 마찰과 쿠션에서 방향을 바꾸는 효과가 더해진다. 좋은 당구 게임은 이 미끄러짐–구름 전환을 따로 모델링한다.
모바일과 디지털 물리
게임 기기의 센서도 물리량을 잰다. 센서 값은 잡음과 치우침이 있는 "측정"이라, 시뮬레이션과는 반대로 그 값에서 원래의 움직임을 거꾸로 추정해야 한다.
- 터치스크린: 정전식 화면은 손가락이 닿은 자리의 전기 용량 변화를 격자로 읽어 좌표를 낸다. 게임에 필요한 것은 좌표보다 움직임이다. 마지막 몇 샘플로 손가락 속도를 구해 손을 뗄 때 그 속도로 던지고(플릭), 마찰 감쇠를 걸어 서서히 멈추게 하면(관성 스크롤) 손에 붙는 느낌이 난다. 두 손가락의 거리와 각도 변화가 확대와 회전이다.
- 가속도계와 자이로: 가속도계는 중력까지 함께 재므로, 가만히 있을 때의 값으로 기울기를 알 수 있고 흔들 때는 중력과 움직임이 섞인다. 저역 통과 필터로 중력을, 나머지로 움직임을 나누는 것이 기본이다(Android 문서). 자이로는 각속도를 재므로 적분하면 방향이 나오지만 오차가 쌓여 흘러간다. 그래서 자이로의 빠른 반응과 가속도계의 느리지만 안 흐르는 중력 방향을 섞는다(상보 필터, 칼만 필터). 컨트롤러 자이로 조준은 컨트롤러 노트에 있다.
- 위치 기반 게임: GPS 위도·경도 두 점 사이 거리는 구 위의 대원 거리라 하버사인 공식으로 구한다. 서울역과 부산역(좌표 어림값)이면 직선 약 329km다. 하늘이 트인 곳에서도 휴대폰 위치는 몇 m씩 흔들려, 그대로 쓰면 가만히 있어도 걸은 거리가 늘어난다. 작은 움직임을 거르고 속도가 사람 걸음으로 말이 되는지 확인한다. 위치 측정의 원리는 위치 노트와 GIS 노트에 있다.
- 압력 센서와 로드셀: 로드셀은 하중에 따라 조금 휘는 금속에 붙인 변형 게이지의 저항 변화를 휘트스톤 브리지로 읽어 무게를 잰다. 판 네 귀퉁이에 로드셀을 두면 힘의 합이 무게, 힘으로 가중 평균한 자리(Σ Fi·pi ÷ Σ Fi)가 압력 중심이라 몸의 기울임을 조작으로 쓸 수 있다.
- 3D 디스플레이: 두 눈에 조금 다른 영상을 보여 주면 뇌가 시차로 깊이를 만든다. 화면까지 거리 D, 눈 사이 e, 보이고 싶은 깊이 Z일 때 화면 위 시차는 e·(Z − D) ÷ Z라, 화면보다 멀면 양수, 가까우면 음수(교차)다. 눈의 초점은 화면에 맞는데 두 눈은 다른 거리로 모이는 어긋남(수렴–조절 불일치)이 피로의 원인으로 꼽힌다. 헤드셋 쪽 이야기는 XR 노트에 있다.
- 광학 추적: 카메라로 표식(빛나는 점, 무늬)을 찾아 그 위치에서 물체의 자세를 역산하거나, 깊이 카메라(구조광, ToF)로 사람의 뼈대를 추정한다. 원리는 거리·깊이 센서 노트와 컴퓨터 비전 노트에 있다.
- 소리: 소리도 물리다. 점음원의 세기는 거리의 제곱에 반비례해 거리가 두 배면 약 6dB 작아지고, 다가오는 음원은 높게, 멀어지는 음원은 낮게 들린다(도플러 효과). 소리의 속도는 20°C 공기에서 약 343m/s라, 멀리서 친 번개나 폭발은 빛보다 늦게 들린다. 게임 오디오 엔진은 이 셋을 거리 감쇠 곡선, 피치 변화, 지연으로 흉내 낸다. 원리는 음향학 노트와 게임 개발 › 사운드 노트에 있다.
흔한 오해
- "dt를 작게 하면 다 해결된다": 오차는 줄지만 계산이 그만큼 늘고, 뻣뻣한 스프링이나 질량비가 큰 사슬처럼 구조적인 문제는 남는다. 적분법, 제약, 반복 수를 함께 봐야 한다.
- "RK4가 가장 좋은 적분법이다": 매끄러운 힘에서는 정확하지만 걸음당 힘 계산이 네 번이고, 충돌처럼 갑자기 바뀌는 힘에서는 그 정확도가 살지 않는다. 오래 돌리면 에너지도 조금씩 빠진다. 게임 강체 엔진이 반암시적 오일러를 기본으로 쓰는 데는 이유가 있다.
- "무거운 물체가 더 빨리 떨어진다": 진공에서는 질량과 상관없이 똑같이 떨어진다. 공기 속에서 차이가 나는 것은 항력 ÷ 질량, 곧 크기에 비해 얼마나 무거운가 때문이다. 깃털과 같은 크기의 쇠공을 떠올리면 된다.
- "반발 계수 1이면 영원히 튄다": 수식으로는 그렇지만, 시뮬레이션은 겹침 보정, 작은 속도 문턱, 적분 오차로 에너지를 조금씩 넣거나 뺀다. 오래 튀는 공이 필요하면 따로 확인하고 조율해야 한다.
- "양력은 윗면 공기가 같은 시간에 도착하려고 빨라져서 생긴다": 이른바 같은 시간 이론은 틀린 설명이다. 실제로 윗면 공기는 뒷전에 더 먼저 닿는다. 날개가 흐름을 아래로 꺾는 것과 그에 따른 압력 차가 양력이다(NASA Incorrect Lift Theory).
- "물리 엔진을 쓰면 현실처럼 된다": 엔진은 안정성과 속도를 위해 많은 근사를 한다. 그리고 재미있는 게임은 현실보다 높은 그립, 공중 조작, 빠른 낙하처럼 일부러 물리를 비튼다. 현실값은 출발점이고, 느낌은 조율로 만든다(게임 조작감 실험실).
핵심 자료
물리 원리는 물리학 노트, 수학 도구는 게임 개발 수학 노트와 미적분 노트, 수치 해석 일반은 계산 과학 노트에 있다.
| 자료 | 종류 | 요지 | 링크 |
|---|---|---|---|
| Game Physics 연재(Integration Basics, Fix Your Timestep!, Physics in 3D, Spring Physics 등) | 글 모음 | 적분법 비교, 고정 시간 간격 누산기와 보간, 3D 강체의 쿼터니언 적분과 정규화, 스프링–댐퍼를 코드와 함께 설명한다. 게임 물리의 출발점으로 가장 많이 추천된다. | Gaffer On Games |
| Box2D 발표 자료 모음 | 발표 자료 | Erin Catto의 GDC 발표들. 순차 충격량(2006), 접촉 매니폴드(2007), 수치 적분(2009), 제약 모델링(2009), 소프트 제약(2011), 연속 충돌(2013), 동적 BVH(2019) 등을 PDF로 공개한다. | box2d.org |
| Physically Based Modeling: Principles and Practice | 강의 노트 | Witkin과 Baraff의 SIGGRAPH 1997 강의. 미분 방정식 기초, 입자 동역학, 암시적 방법, 제약 동역학, 강체 동역학(무제약·접촉)을 수식부터 다룬다. | Carnegie Mellon University |
| Ten Minute Physics | 영상 강좌 | 10분 남짓한 회마다 대포알, 위치 기반 동역학, 천, 유체, 강체 시뮬레이션을 브라우저에서 돌아가는 JavaScript 예제와 함께 보여 준다. | matthias-research.github.io |
| Beginner's Guide to Aeronautics: Lift Equation, Drag Equation | 교육 자료 | 양력 L = C_L·½ρV²·A, 항력 D = C_d·½ρV²·A와 계수·기준 면적의 뜻을 설명한다. 비행기·투사체·자동차 공기 저항 모델의 근거다. | NASA Glenn Research Center |
| The Physics of Baseball | 연구 사이트 | Alan Nathan의 야구 물리 연구. 배트–공 충돌, 항력과 마그누스 힘, 궤적 계산기와 투구 회전 분석 자료가 있다. | University of Illinois |
| Motion sensors | 공식 문서 | 가속도계 값에 중력이 들어 있다는 것, 중력 센서와 선형 가속도 센서의 관계, 저역·고역 통과 필터로 둘을 나누는 법을 설명한다. | Android Developers |
| University Physics Volume 1 | 무료 교과서 | 운동학, 뉴턴 법칙, 에너지, 운동량과 충돌, 회전과 관성 모멘트, 진동을 대학 1학년 수준으로 다룬다. 이 노트의 물리 원리 쪽 기준이다. | OpenStax |
책 목차와 대조: 『게임 개발자를 위한 물리(개정2판)』
이 노트는 브라이언 비발레츠·데이비드 버그의 『게임 개발자를 위한 물리(개정2판)』(한빛미디어, 2014, 원서 Physics for Game Developers 2nd Edition, O'Reilly 2013)가 다루는 주제를 지도로 삼았다. 책의 설명과 예제를 옮기지 않았고, 설명과 그림은 직접 쓰고 계산했다. 아래는 출판사 페이지(한빛미디어 책 페이지)의 장 목록과, 그 주제를 맡은 이 노트의 절이다.
| 부 | 장 | 장 제목 | 이 노트의 절 |
|---|---|---|---|
| I 물리학의 기초 | 1 | 기본 개념 | 게임 물리 루프, 단위, 운동 방정식 |
| I 물리학의 기초 | 2 | 운동학 | 게임 물리 루프, 단위, 운동 방정식 |
| I 물리학의 기초 | 3 | 힘 | 게임 물리 루프, 단위, 운동 방정식, 비행기와 배: 공기와 물이 주는 힘 |
| I 물리학의 기초 | 4 | 동역학 | 게임 물리 루프, 단위, 운동 방정식, 2D 강체: 질량 중심과 관성 모멘트 |
| I 물리학의 기초 | 5 | 충돌 | 충돌 검출에서 충돌 응답까지 |
| I 물리학의 기초 | 6 | 발사체 | 투사체: 중력, 항력, 바람, 마그누스 |
| II 리지드바디 동역학 | 7 | 실시간 시뮬레이션 | 수치 적분 네 가지와 에너지 드리프트 |
| II 리지드바디 동역학 | 8 | 파티클 | 입자 시스템 |
| II 리지드바디 동역학 | 9 | 2D 리지드바디 시뮬레이터 | 2D 강체: 질량 중심과 관성 모멘트 |
| II 리지드바디 동역학 | 10 | 충돌반응 구현하기 | 충돌 검출에서 충돌 응답까지 |
| II 리지드바디 동역학 | 11 | 3D 리지드바디 시뮬레이션에서의 회전 | 3D 회전: 관성 텐서, 각속도, 쿼터니언 |
| II 리지드바디 동역학 | 12 | 3D 리지드바디 시뮬레이션 | 3D 회전: 관성 텐서, 각속도, 쿼터니언 |
| II 리지드바디 동역학 | 13 | 연결된 물체 | 스프링, 댐퍼, 제약 조건 |
| II 리지드바디 동역학 | 14 | 물리엔진 | 물리 엔진의 구조 |
| III 물리모델 만들기 | 15 | 비행기 | 비행기와 배: 공기와 물이 주는 힘 |
| III 물리모델 만들기 | 16 | 배 | 비행기와 배: 공기와 물이 주는 힘 |
| III 물리모델 만들기 | 17 | 차량과 호버크라프트 | 차량과 호버크래프트 |
| III 물리모델 만들기 | 18 | 총과 폭발 | 총탄과 폭발 |
| III 물리모델 만들기 | 19 | 스포츠 | 스포츠: 회전하는 공과 당구 |
| IV 디지털 물리 | 20 | 터치스크린 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 21 | 가속도계 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 22 | 위치기반 게임 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 23 | 압력센서와 로드셀 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 24 | 3D 디스플레이 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 25 | 광학추적기법 | 모바일과 디지털 물리 |
| IV 디지털 물리 | 26 | 소리 | 모바일과 디지털 물리 |
부록(벡터, 행렬, 쿼터니언 연산)은 게임 개발 수학 노트와 선형대수 노트가 맡는다.
- Game Physics 연재(Integration Basics, Fix Your Timestep!, Physics in 3D, Spring Physics 등) — Gaffer On Games
- Box2D 발표 자료 모음 — box2d.org
- Physically Based Modeling: Principles and Practice — Carnegie Mellon University
- Ten Minute Physics — matthias-research.github.io
- Beginner's Guide to Aeronautics: Lift Equation, Drag Equation — NASA Glenn Research Center
- The Physics of Baseball — University of Illinois
- Motion sensors — Android Developers
- University Physics Volume 1 — OpenStax
- Integration Basics — Gaffer On Games
- Fix Your Timestep! — Gaffer On Games
- Physics in 3D — Gaffer On Games
- Spring Physics — Gaffer On Games
- Fast and Simple Physics using Sequential Impulses (GDC 2006) — Erin Catto
- Soft Constraints (GDC 2011) — Erin Catto
- Numerical Methods (GDC 2015) — Erin Catto
- Jolt Physics — GitHub
- Box2D Documentation — box2d.org
- Drag Equation — NASA Glenn Research Center
- What is Lift? — NASA Glenn Research Center
- Incorrect Lift Theory — NASA Glenn Research Center
- Calculate distance and bearing between two Latitude/Longitude points — Movable Type Scripts
- HyperPhysics — Georgia State University
- 게임 개발자를 위한 물리(개정2판) — 한빛미디어