물리 시뮬레이션 핵심 정리

물리 시뮬레이션은 실제 세계의 연속적인 물리 현상을 컴퓨터가 일정한 시간 간격으로 근사하여 계산하는 과정이다.

현실에서는 물리량이 시간에 따라 연속적으로 변하지만, 컴퓨터는 무한히 작은 시간 간격을 계산할 수 없다.

따라서

연속적인 물리 법칙 -> 시간 구간으로 분할 -> 매 Time Step마다 상태 계산 -> 다음 상태로 갱신

하는 방식으로 시뮬레이션한다.

핵심은 결국 미분방정식을 어떻게 시간에 따라 수치적으로 풀 것인가에 있다.


연속 시간과 이산 시간

현실의 물리 현상은 기본적으로 연속 시간(Continuous Time)에서 발생한다.

예를 들어 위치 x와 속도 v는 시간에 따라 연속적으로 변한다.

x(t)

v(t)

그리고

v = dx/dt

a = dv/dt

이다.

하지만 컴퓨터 시뮬레이션에서는 모든 순간을 계산할 수 없다.

따라서 특정 시간 간격마다 상태를 계산한다.

t_0 -> t_1 -> t_2 -> t_3 -> ...

이것이 이산 시간(Discrete Time)이다.

결국

현실 -> 연속 시간

컴퓨터 시뮬레이션 -> 이산 시간

이라고 볼 수 있다.


Time Step

Time Step Δt는 한 번의 물리 계산에서 시간이 얼마나 진행되는지를 나타낸다.

예를 들어

Δt = 0.02 s

라면 한 번 계산할 때마다 물리 시간이 0.02초 진행된다.

기본적인 시뮬레이션 구조는

현재 상태 -> 물리 계산 -> Δt만큼 진행 -> 다음 상태

이다.

Time Step이 작으면 일반적으로 더 정확한 계산이 가능하지만 계산량이 증가한다.

Δt 감소 -> 정확도 증가 / 계산량 증가

반대로

Δt 증가 -> 계산량 감소 / 수치 오차 증가 / 불안정 가능성 증가

한다.


Fixed Time Step

Fixed Time Step은 물리 계산의 시간 간격을 항상 일정하게 유지하는 방식이다.

예를 들어

Δt = 0.02 s

를 사용한다면 모든 물리 업데이트를 동일한 시간 간격으로 계산한다.

0.00 -> 0.02 -> 0.04 -> 0.06 -> ...

이 방식은 물리 시뮬레이션에서 중요하다.

프레임 렌더링 시간은 컴퓨터 성능에 따라 계속 변할 수 있기 때문이다.

예를 들어 렌더링 프레임이

16 ms -> 18 ms -> 12 ms -> 25 ms

처럼 변하더라도 물리 계산은

20 ms -> 20 ms -> 20 ms -> 20 ms

로 유지할 수 있다.

따라서

Render Frame Rate != Physics Time Step

으로 분리하는 것이 일반적이다.

게임에서는

렌더링 -> 가변 프레임

물리 -> 고정 시간 간격

구조를 사용하는 경우가 많다.


수치 적분

물리 시뮬레이션에서 가장 중요한 개념 중 하나다.

물리 법칙은 대부분 미분방정식 형태로 표현된다.

예를 들어

F = ma

에서

a = dv/dt

이므로

dv/dt = F/m

이다.

하지만 컴퓨터는 일반적인 상황에서 이 미분방정식의 정확한 해를 직접 구하기 어렵다.

따라서 현재 상태에서 다음 상태를 근사 계산한다.

이 과정을 수치 적분(Numerical Integration)이라고 한다.

기본 흐름은

힘 -> 가속도 -> 속도 변화 -> 위치 변화

이다.


Euler Integration

가장 단순한 수치 적분 방법이다.

현재 시점의 속도와 가속도를 사용하여 다음 상태를 예측한다.

속도는

v_next = v + aΔt

위치는

x_next = x + vΔt

로 계산한다.

구조는

현재 상태 -> 현재 가속도 계산 -> 속도 갱신 -> 위치 갱신

이다.

장점

구현이 매우 간단하다.

O(1) 계산

으로 상태를 갱신할 수 있으며 이해하기도 쉽다.

단점

수치 오차가 누적된다.

특히 스프링이나 충돌처럼 민감한 시스템에서는 Time Step이 크면 불안정해질 수 있다.

Δt 증가 -> 오차 증가 -> 불안정 가능성 증가


Semi-Implicit Euler

Semi-Implicit Euler는 게임 물리에서 매우 중요한 적분 방식이다.

먼저 속도를 갱신하고, 갱신된 속도를 이용하여 위치를 갱신한다.

v_next = v + aΔt

x_next = x + v_nextΔt

일반적인 Euler와 위치 계산 순서가 다르다.

Euler는

위치 -> 현재 속도 사용

Semi-Implicit Euler는

속도 갱신 -> 갱신된 속도로 위치 계산

이다.

이 작은 차이가 물리 시뮬레이션의 안정성에 큰 영향을 준다.

특히

스프링

중력

충돌

강체

등의 시뮬레이션에서 단순 Euler보다 안정적인 경우가 많다.

게임 엔진의 실시간 물리 계산에서 매우 흔하게 사용되는 방식이다.


Euler와 Semi-Implicit Euler 비교

두 방법의 차이는 위치 갱신에 어떤 속도를 사용하느냐이다.

Euler

v_next = v + aΔt

x_next = x + vΔt

Semi-Implicit Euler

v_next = v + aΔt

x_next = x + v_nextΔt

둘 다 속도 업데이트는 동일하지만 위치 업데이트가 다르다.

결과적으로 Semi-Implicit Euler가 에너지 보존 특성과 안정성 측면에서 더 좋은 경우가 많다.

특히 진동 시스템에서는 차이가 크게 나타날 수 있다.


Verlet Integration

Verlet Integration은 위치 기반으로 물리 상태를 적분하는 방법이다.

기본적인 Verlet 형태는

x_next = 2x - x_prev + aΔt²

이다.

현재 위치와 이전 위치를 이용하여 다음 위치를 계산한다.

이전 위치 + 현재 위치 + 가속도 -> 다음 위치

가 되는 구조다.

속도를 직접 저장하지 않는 기본 Verlet도 존재하며, 속도는 위치 차이로 근사할 수 있다.

v ≈ (x_next - x_prev)/(2Δt)

Verlet은 위치 제약을 다루는 시스템에서 특히 유용하다.

예를 들어

천 시뮬레이션

로프

입자 시스템

제약 기반 물리

등에서 활용된다.


Runge-Kutta

Runge-Kutta(RK)는 한 Time Step 안에서 여러 지점의 미분값을 평가하여 더 정확한 다음 상태를 계산하는 방법이다.

대표적인 것이 RK4다.

Euler가

현재 시점의 기울기 -> 다음 상태 예측

을 사용하는 반면,

RK4는 한 Time Step 안에서 여러 번 기울기를 평가한다.

개념적으로

현재 상태 -> k1

중간 상태 -> k2

중간 상태 -> k3

다음 상태 -> k4

를 계산한 후 이를 가중 평균한다.

RK4의 핵심은

한 번의 단순한 기울기 평가 -> 여러 기울기 평가 -> 더 정확한 적분

이다.

정확도는 높지만 계산량도 증가한다.

따라서 실시간 게임 물리 전체에 무조건 RK4를 사용하는 것이 좋은 것은 아니다.


적분 방법 비교

방법특징장점단점
Euler현재 상태의 미분값 사용단순하고 빠름오차와 불안정성
Semi-Implicit Euler속도 먼저 갱신게임 물리에 적합고정밀 적분에는 한계
Verlet이전/현재 위치 사용위치 제약에 유리일반적인 속도 기반 시스템에는 추가 처리 필요
RK4여러 지점 평가높은 정확도계산량 증가

핵심적인 선택은

단순성 -> Euler

실시간 게임 물리 -> Semi-Implicit Euler

위치/제약 중심 -> Verlet

높은 적분 정확도 -> RK4

정도로 이해하면 된다.


수치 오차

컴퓨터에서 수치 적분은 실제 해를 근사하기 때문에 오차가 발생한다.

대표적으로 절단 오차(Truncation Error)반올림 오차(Round-off Error)가 있다.

절단 오차

수학적으로 존재하는 항들을 일부 생략하면서 발생하는 오차다.

Euler는 낮은 차수의 근사이기 때문에 Time Step이 커질수록 오차가 커진다.

Δt 증가 -> 근사 오차 증가

반올림 오차

컴퓨터가 실수를 무한한 정밀도로 저장할 수 없기 때문에 발생한다.

예를 들어 부동소수점 연산에서는 아주 작은 오차가 계속 발생할 수 있다.

반복적인 물리 계산에서는 이러한 오차가 누적될 수 있다.


오차의 누적

물리 시뮬레이션에서는 한 번의 계산 오차보다 시간이 지나면서 오차가 어떻게 누적되는가가 중요하다.

예를 들어 이상적인 시스템에서 에너지가 일정해야 하는데

E_0 -> E_1 -> E_2 -> E_3 -> ...

하면서 계속 증가한다면 시스템이 실제 물리와 다르게 폭주할 수 있다.

반대로 에너지가 지나치게 감소하면 물체의 움직임이 빠르게 죽어버릴 수 있다.

따라서 수치 적분에서는

정확도

뿐만 아니라

에너지 거동

안정성

오차 누적

을 함께 봐야 한다.


안정성

수치 안정성(Numerical Stability)은 작은 계산 오차가 시간이 지나면서 폭발적으로 증가하지 않는 성질이다.

물리 시뮬레이션에서는 매우 중요하다.

특히

스프링

충돌

고속 물체

큰 질량 차이

강한 힘

등에서 안정성이 문제가 되기 쉽다.

예를 들어 Time Step이 지나치게 크면

큰 Δt -> 큰 상태 변화 -> 적분 오차 증가 -> 에너지 폭주 -> 시뮬레이션 불안정

이 발생할 수 있다.

대표적인 증상은

물체가 갑자기 튐

스프링이 폭발함

충돌 후 속도가 비정상적으로 증가함

물체가 지면을 뚫음

시뮬레이션이 NaN으로 오염됨

등이다.


Time Step과 안정성

Time Step은 단순히 “업데이트 빈도”가 아니다.

물리 시스템의 특성에 따라 안정적으로 사용할 수 있는 시간 간격의 범위가 존재한다.

예를 들어 매우 강한 스프링은

k 증가 -> 시스템 변화 속도 증가 -> 더 작은 Δt 필요

가 될 수 있다.

반대로 변화가 느린 시스템은 상대적으로 큰 Time Step을 사용할 수 있다.

따라서

물리 시스템의 시간 스케일 -> 적절한 Δt 결정

이라는 관점이 중요하다.


Fixed Time Step과 프레임

게임에서 렌더링과 물리 계산의 시간 간격을 분리하면 구조가 깔끔해진다.

예를 들어 렌더링 프레임은

Frame -> Frame -> Frame -> Frame

으로 실행되지만 물리 계산은

Physics -> Physics -> Physics -> Physics

고정된 Δt로 실행한다.

프레임이 너무 오래 걸리면 한 프레임에서 여러 번 물리 Step을 수행할 수도 있다.

실제 경과 시간 -> Physics Step 누적 -> Δt만큼 반복 계산

이 방식은 프레임 속도가 변해도 물리 시간의 진행을 일정하게 유지하는 데 유리하다.

다만 프레임이 지나치게 느려지면 물리 계산량이 폭증하는 문제가 생길 수 있다.

이를 흔히 Spiral of Death라고 한다.

성능 저하 -> Physics Step 증가 -> 계산량 증가 -> 더 큰 성능 저하

라는 악순환이다.

실제 엔진에서는 물리 Step 수에 제한을 두는 등의 방법으로 방어한다.


물리 시뮬레이션의 기본 루프

가장 기본적인 구조는 다음과 같다.

현재 상태 -> 힘 계산 -> 가속도 계산 -> 수치 적분 -> 다음 상태

뉴턴의 운동 법칙을 적용하면

F -> a = F/m

이후 적분을 통해

a -> v

v -> x

를 계산한다.

전체적으로

Force -> Acceleration -> Integration -> Velocity -> Position

이다.


게임 물리의 실제 구조

실제 게임 물리 엔진에서는 단순히 적분만 하는 것이 아니다.

대략적으로

입력/외력 -> 힘 계산 -> 충돌 검출 -> 접촉 제약 -> 충돌 해결 -> 속도 적분 -> 위치 적분 -> 상태 갱신

과 같은 여러 단계가 연결된다.

특히 충돌과 접촉이 들어오면 단순한 미분방정식만으로 해결되지 않는다.

연속적인 운동 + 이산적인 충돌 이벤트 + 접촉 제약

을 함께 처리해야 한다.


핵심 정리

연속 시간 -> 현실의 물리 현상

이산 시간 -> 컴퓨터가 계산하는 물리 시간

Time Step -> Δt

Fixed Time Step -> 일정한 Δt로 물리 계산

수치 적분 -> 미분방정식을 이산 시간에서 근사적으로 계산

Euler -> 현재 미분값으로 다음 상태 계산

Euler -> v_next = v + aΔt

Euler -> x_next = x + vΔt

Semi-Implicit Euler -> 속도를 먼저 갱신한 후 위치 갱신

Semi-Implicit Euler -> v_next = v + aΔt

Semi-Implicit Euler -> x_next = x + v_nextΔt

Verlet -> 이전 위치와 현재 위치를 이용하여 다음 위치 계산

Verlet -> x_next = 2x - x_prev + aΔt²

RK4 -> 한 Time Step에서 여러 기울기를 평가하여 적분

수치 오차 -> 근사와 부동소수점 연산에서 발생

Δt 증가 -> 일반적으로 수치 오차 증가

안정성 -> 오차가 시간에 따라 폭발하지 않는 성질

강한 힘/빠른 변화 -> 작은 Δt 필요

렌더링 시간 != 물리 Time Step

전체 구조는 다음과 같이 정리할 수 있다.

물리 법칙 -> 미분방정식 -> 수치 적분 -> 이산 시간 상태 -> 다음 상태

게임에서는

Render Frame -> Fixed Physics Step -> Physics Simulation -> State Update

가 기본적인 구조다.

그리고 적분기의 선택은

Euler -> 단순하지만 불안정할 수 있음

Semi-Implicit Euler -> 게임 물리에 적합한 기본 선택

Verlet -> 위치/제약 기반 시스템에 유리

RK4 -> 높은 정확도 대신 높은 계산량

으로 정리할 수 있다.

결국 물리 시뮬레이션의 본질은 연속적인 물리 법칙을 컴퓨터가 처리할 수 있는 이산적인 시간 단계로 변환하고, 수치 적분을 통해 매 순간의 상태를 근사적으로 갱신하는 것이다. 정확한 물리 법칙을 구현하는 것만으로 충분하지 않다. Time Step, 적분 방법, 오차 누적, 안정성까지 함께 설계해야 실제로 사용할 수 있는 시뮬레이션이 된다.