Making Motion Feel Alive

Physics as a Creative Tool

Form → Motion → Behavior → System

물리 시뮬레이션과 운동 제어를 통한 Procedural Art

2026 · Creative Coding Study

이 프레젠테이션에서 다루는 내용:

  • 왜 랜덤만으로는 부족한가
  • 파티클 시스템과 벡터 연산
  • 힘(Force)과 통합(Integration)
  • 스프링, 제약조건, 플로우 필드
  • 실용적인 코드 예제와 활용법

왜 랜덤은 금방 지루해질까?

같이 한번 생각해봐요

Math.random()
Time-accumulated

순수 랜덤의 문제

  • 매 프레임 독립적인 값 생성
  • 이전 상태와의 연결 없음
  • 예측 불가능 = 무의미한 혼돈
  • 인간의 뇌가 패턴을 찾지 못함

재밌는 사실: 인간의 뇌는 초당 약 60개의 "스냅샷"을 처리해요. 프레임마다 완전히 다른 위치면 뇌가 "이건 같은 물체다"라고 인식을 못 해요!

시간 누적의 효과

  • 이전 프레임의 값이 다음에 영향
  • 연속성 = 추적 가능한 움직임
  • 예측 가능하되 완전히 결정적이지 않음
  • 뇌가 '생명'으로 인식

전문 용어로: 이걸 Markov Property라고 해요. "현재 상태가 다음 상태를 결정한다"는 개념이에요.

핵심 인사이트: 랜덤은 "상태"만 만든다. 생명감은 시간에 따른 변화 규칙에서 나온다.

함께 생각해보기: White Noise vs Brownian Motion

왼쪽 데모는 White Noise - 모든 프레임이 독립적이에요. 오른쪽은 Brownian Motion(브라운 운동)의 원리를 따라요. 1827년 로버트 브라운이 꽃가루를 현미경으로 관찰하다가 발견한 움직임이에요. 물 분자가 꽃가루를 무작위로 밀어대지만, 꽃가루는 연속적인 궤적을 그려요. 자연의 "랜덤"도 사실은 누적된 랜덤이에요!

발표 포인트: 많은 초보자들이 Math.random()만으로 자연스러운 움직임을 만들려고 합니다. 왼쪽 데모를 보세요 - 점들이 깜빡이듯 무작위로 움직입니다. 이건 "노이즈"지 "움직임"이 아닙니다.

오른쪽을 보세요. 같은 랜덤 요소가 있지만, 시간에 따라 누적됩니다. position += velocity 같은 간단한 공식만으로도 이 차이가 납니다.

핵심 질문: "생명체는 어떻게 움직이나요?" - 이전 상태를 기억하고, 그것을 바탕으로 다음 상태를 결정합니다.

심화: White Noise는 주파수 스펙트럼이 평탄해요. Brownian Motion(1/f² noise)은 저주파가 강해서 더 "부드럽게" 느껴져요. 이게 바로 Perlin Noise가 자연스러운 이유이기도 해요!

우리는 형태를 그리는 사람이 아니라,
규칙을 설계하는 사람이다

같은 점 하나가 규칙에 따라 완전히 다른 움직임을 보여준다:

  • Linear — 단순 왕복, 기계적 느낌 (pos.x = sin(time))
  • Circular — 궤도 운동, 안정적 순환 (cos, sin 조합)
  • Noise — 유기적 배회, 자연스러운 탐색 (Perlin noise)
  • Spring — 탄성 추종, 감정적 반응 (물리 기반)

핵심 메시지: Procedural Art에서 우리의 역할은 "무엇을 그릴까"가 아니라 "어떤 규칙을 적용할까"입니다.

각 버튼을 클릭하면서 같은 점이 어떻게 다르게 움직이는지 보여주세요. 코드 한 줄의 차이가 전혀 다른 "성격"을 만듭니다.

실습 아이디어: 청중에게 "어떤 규칙이 가장 생명체 같나요?"라고 물어보세요. 대부분 Noise나 Spring을 선택합니다.

Creative Coding Physics Map

크리에이티브 코딩에서 가장 자주 사용되는 물리 개념들

  • Particle — 존재의 최소 단위. position, velocity, acceleration
  • Force — 움직임의 원인. 중력, 마찰, 끌어당김, 밀어냄
  • Integration — 시간을 어떻게 계산할 것인가. Euler vs Verlet
  • Constraint — 형태를 유지하는 제약조건. 거리, 각도, 충돌
  • Flow — 공간에 방향성 부여. Flow Field, Curl Noise

오늘 다루지 않는 것: 정밀한 유체 역학(Navier-Stokes), 강체 물리(Rigid Body), 지형 생성

목표: 즉각적으로 시각적 결과가 나오는, 창작에 바로 활용 가능한 기법들

여기가 모든 것의 시작점이에요!

Particle = 최소 생명 단위

Particle은 점이 아니라 '행동하는 존재'다

class Particle {
  position: Vector  // 현재 위치 (x, y)
  velocity: Vector  // 속도 = 방향 + 크기
  acceleration: Vector  // 가속도 (힘의 결과)
  mass: number  // 질량 (관성의 척도)
}
v = v + a → p = p + v
매 프레임: 가속도→속도→위치 순으로 업데이트

잠깐! 벡터(Vector)가 뭐예요?

벡터 = 방향 + 크기를 동시에 표현하는 화살표예요. (3, 4)라는 벡터는 "오른쪽으로 3, 위로 4 이동"이라는 의미죠. 크기(magnitude)는 √(3²+4²) = 5예요. 피타고라스 정리가 여기서 쓰여요!

  • 모든 파티클 시스템의 기본 구조
  • 1개든 10,000개든 동일한 물리 법칙
  • 개별 행동 → 집단 패턴 (Emergence)

필수 벡터 연산 4가지

// 1. 덧셈: 힘 합치기
v1 + v2 = (v1.x + v2.x, v1.y + v2.y)

// 2. 스칼라 곱: 크기 조절
v × 2 = (v.x × 2, v.y × 2)

// 3. 정규화: 방향만 추출 (크기=1)
normalize(v) = v / |v|

// 4. 크기(magnitude)
|v| = √(v.x² + v.y²)

왜 acceleration을 매 프레임 초기화할까?

힘(Force)은 순간적이에요. 손으로 공을 밀면 미는 그 순간만 힘이 작용하죠. 하지만 속도(velocity)는 누적돼요. 한번 밀린 공은 계속 굴러가요.

그래서 update() 끝에 acceleration.set(0, 0)을 해줘요. 다음 프레임에 새로운 힘만 반영되도록요!

핵심 개념: Particle은 물리학의 "질점"과 같습니다. 크기는 무시하고 위치만 가진 점이지만, velocity와 acceleration이 추가되면서 "행동"이 생깁니다.

데모 설명: 화면의 공이 벽에 부딪히며 튕기는 것을 보세요. 위치(position), 속도(velocity), 힘(force/acceleration)이 표시됩니다. 흰색 선이 속도, 노란색 선이 현재 작용하는 힘입니다.

실무 팁: 처음에는 파티클 1개로 시작하세요. 1개가 제대로 움직이면 1000개도 똑같이 움직입니다.

심화 - 왜 미분/적분인가: 물리에서 position의 시간 미분이 velocity, velocity의 시간 미분이 acceleration이에요. 우리가 하는 건 그 역방향(적분)이에요. acceleration → velocity → position 순으로 "쌓아가는" 거죠!

참고: Nature of Code: Vectors ·

1.0
0.10
0.990
0.80
0.15

Force: 방향을 가진 의도

Force는 숫자가 아니라 벡터다. 방향과 크기를 가진 의도의 표현.

버튼을 조합해서 실험해봐요! 물리학이 장난감처럼 느껴질 거예요

Gravity (중력)

항상 아래로 작용하는 일정한 힘.
F = (0, 0.1)

실제 중력: 9.8m/s². 게임에선 "느낌"으로 조절!

Attract (끌어당김)

목표 지점을 향해 작용.
F = normalize(target - pos) × strength

거리 제곱에 반비례하면 "진짜" 중력!

Noise Force

위치 기반 의사 랜덤 방향.
F = fromAngle(noise(x, y) × 2π)

새떼, 물고기떼 시뮬레이션의 기초!

F = m × a  →  a = F / m
뉴턴의 제2법칙: 질량이 클수록 같은 힘에 덜 반응 (관성!)

Force Accumulation이란?

매 프레임 여러 힘이 동시에 작용해요:
F_total = F_gravity + F_wind + F_attract
이 합쳐진 벡터 하나가 최종 가속도를 결정!

자주 쓰는 힘들

• Friction: F = -v × c (속도 반대 방향)
• Drag: F = -v × |v| × c (속도²에 비례)
• Repel: Attract의 반대 (밀어냄)

실험해보기: Gravity + Attract를 동시에 켜면? 떨어지면서 마우스 쪽으로 휘어져요. 이게 중첩의 원리(Superposition)!

인터랙션 가이드: 마우스를 움직여보세요. 파티클들이 마우스를 향해 끌려옵니다. 버튼을 조합해서 여러 힘을 동시에 적용할 수 있습니다.

실험: Gravity + Attract를 동시에 켜면 어떻게 될까요? 중력으로 떨어지면서도 마우스를 향해 휘어집니다. 이것이 벡터 합의 힘입니다.

크리에이티브 팁: Noise Force만 켜면 유기적인 군집 행동이 나타납니다. 새떼, 물고기떼 시뮬레이션의 기초입니다.

심화 - 만유인력: F = G × m1 × m2 / r². 거리의 제곱에 반비례하는 진짜 중력! 행성 궤도 시뮬레이션에 사용해요.

참고: Nature of Code: Forces · Newton's Laws (Wikipedia) · Coding Train: Gravitational Attraction

0.980
100

Integration: 시간을 어떻게 계산할 것인가

같은 힘이라도 적분 방법에 따라 완전히 다른 움직임

조금 수학적인 얘기지만, 같이 알아보면 재밌어요!

Euler Integration
Verlet Integration

Euler Integration (오일러)

velocity += acceleration × dt
position += velocity × dt
  • 구현이 단순함 (1707년 레온하르트 오일러)
  • 높은 속도에서 불안정
  • 에너지가 누적되어 폭발 가능

왜 폭발? 매 스텝마다 약간의 오차가 생기는데, 그 오차가 다음 스텝의 입력이 돼서 점점 커져요. 이걸 "에너지 드리프트"라고 해요.

Verlet Integration (베를레)

// 속도를 저장하지 않아요!
temp = position
position = 2×position - oldPos + a×dt²
oldPosition = temp
  • 이전 위치를 "기억" (1791년 베를레)
  • 시간 역행 대칭성 (time-reversible)
  • Constraint 처리에 최적

왜 안정? 속도를 "암묵적"으로 계산해서 오차가 누적되지 않아요. 제약조건 풀 때 위치만 건드리면 속도도 자동 반영!

함께 이해하기: 왜 "적분(Integration)"이라고 부를까?

물리학에서 가속도 a = dv/dt (속도의 시간 미분)이에요. 반대로 v = ∫a dt (가속도의 적분)가 되죠.
컴퓨터는 연속적인 적분을 못 하니까 v ≈ v + a×Δt로 근사해요. 이게 바로 "수치 적분(Numerical Integration)"!
Δt가 작을수록 정확하지만, 계산량은 늘어나요. 게임은 보통 1/60초(16.67ms)를 써요.

실무 팁: 대부분의 크리에이티브 코딩에선 Euler로 충분해요. 하지만 천(cloth)이나 로프(rope)를 만들려면 Verlet이 거의 필수예요!

왜 중요한가: Integration은 "미분의 역연산"입니다. 가속도(a)를 적분하면 속도(v), 속도를 적분하면 위치(p)가 됩니다. 하지만 컴퓨터는 연속적인 적분을 할 수 없어서 이산적으로 근사합니다.

Euler의 문제: 마우스를 빠르게 움직여보세요. Euler(왼쪽)는 공이 불안정하게 진동하거나 튕겨나갈 수 있습니다. 이를 "numerical instability"라고 합니다.

Verlet의 강점: 속도를 직접 저장하지 않고 "현재 위치 - 이전 위치"로 암묵적으로 계산합니다. 이 방식이 constraint(거리 제약) 처리에 매우 좋습니다.

더 알고 싶다면: RK4(Runge-Kutta 4차)도 있어요. 더 정확하지만 4배 느려요. 과학 시뮬레이션에서 주로 써요.

실무 선택 가이드:
- 간단한 파티클 효과 → Euler로 충분
- 천, 로프, 체인 시뮬레이션 → Verlet 필수
- 게임 물리 엔진 → 대부분 Verlet 변형 사용

참고: Verlet Integration (Wikipedia) · Coding Train: Verlet Physics · Gaffer on Games: Integration Basics

Spring: 가장 많이 쓰이는 마법

탄성(Elasticity)은 감정을 만든다

UI 애니메이션의 80%는 이 원리로 만들어져요!

F = -k × (position - target) - c × velocity
Hooke의 법칙 + Damping: 복원력 + 감쇠력

Stiffness (강성) k

  • 높음(0.15) → 빠르고 즉각적인 반응
  • 낮음(0.02) → 느리고 부드러운 움직임
  • UI 버튼 호버: 0.1 ~ 0.15
  • 카메라 팔로우: 0.02 ~ 0.05

기타 줄을 생각해봐요. 팽팽할수록(k↑) 더 빠르게 진동하죠!

Damping (감쇠) c

  • 낮음(0.85) → 오래 흔들림 (탱탱볼)
  • 높음(0.99) → 빠르게 정지 (젤리)
  • 공식: velocity *= (1 - damping)
  • 0 = 영원히 진동, 1 = 즉시 정지

자동차 서스펜션과 같아요. 충격을 흡수하죠!

함께 알아보기: 임계 감쇠(Critical Damping)란?

스프링 시스템에는 세 가지 상태가 있어요:
• Underdamped (감쇠 부족): 목표를 지나쳐서 왔다갔다 진동해요 → 탱탱볼, 젤리
• Critically Damped (임계 감쇠): 진동 없이 가장 빠르게 도달해요 → 문 닫히는 속도
• Overdamped (과감쇠): 느리지만 진동 없이 도달해요 → 점성이 높은 액체
임계 감쇠 조건: c = 2√(k×m). UI에선 보통 살짝 underdamped가 더 "살아있는" 느낌!

어디서 많이 봤을까? iOS 스크롤 바운스, MacOS 창 최소화, 안드로이드 오버스크롤, 웹의 Framer Motion/react-spring 전부 Spring 기반이에요!

왜 Spring이 "마법"인가: 가장 적은 코드로 가장 자연스러운 움직임을 만듭니다. lerp(선형 보간)보다 훨씬 생동감 있습니다.

lerp vs Spring: lerp는 "남은 거리의 일정 비율만큼 이동"이에요. Spring은 "목표와의 거리에 비례하는 힘 + 속도에 비례하는 저항"이에요. Spring은 overshoot(지나침)이 가능해서 더 역동적이죠!

슬라이더 실험: Stiffness를 최대로 → 딱딱한 느낌. 최소로 → 나른한 느낌. Damping을 최소로 → 계속 흔들림. 최대로 → 한번에 멈춤.

실무 꿀팁:
- iOS의 탄성 스크롤 = Spring + 낮은 damping
- 마우스 커서 따라가기 = Spring + 중간 stiffness
- 알림 팝업 등장 = Spring + 높은 stiffness, 낮은 damping (bounce 효과)

주의: stiffness가 너무 높고 damping이 너무 높으면 진동이 발산할 수 있습니다. 실제로는 0.1 이하의 stiffness가 안전합니다.

참고: A Friendly Intro to Spring Physics · react-spring 라이브러리 · Framer Motion

Damping
Stiffness

Constraint: 형태는 유지되는 것이다

천, 로프, 젤리의 비밀을 같이 파헤쳐봐요!

형태를 "그리는" 게 아니라, 물리적 제약을 통해 "유지"한다

Distance Constraint

두 점 사이 거리 유지
→ 체인, 로프, 천 구조

가장 기본이자 가장 강력!

Position Based Dynamics

위치를 직접 조정
→ 속도 기반보다 안정적

2006년 Müller 논문이 시초

Iterative Solving

여러 번 반복 계산
→ 3~5회로 충분히 안정

Gauss-Seidel 방식!

// Distance Constraint 해결 (핵심 알고리즘)
diff = p2.pos - p1.pos
distance = diff.length()
correction = (restLength - distance) / distance × 0.5
p1.pos -= diff × correction  // 각각 절반씩 이동
p2.pos += diff × correction

왜 "위치 기반(Position Based)"이 좋을까?

기존 방식: 힘 → 가속도 → 속도 → 위치 (간접적)
PBD 방식: 위치를 직접 "당겨서" 제약 만족

장점: Verlet과 궁합이 완벽! 위치만 바꿔도 속도가 자동으로 반영돼요. 폭발(발산)도 거의 없어요!

왜 반복(Iteration)이 필요할까?

제약조건 A를 풀면 → 제약조건 B가 깨지고
제약조건 B를 풀면 → 제약조건 C가 깨지고...

반복하면 점점 균형점에 수렴! 이게 Gauss-Seidel 반복법이에요.

재밌는 사실: Unity, Unreal, Blender의 천/헤어 시뮬레이션 모두 PBD 기반이에요. 게임 업계 표준이 된 2006년 논문 하나의 위력!

데모 설명: Constraint ON 상태에서 천이 자연스럽게 늘어집니다. OFF로 끄면? 모든 점이 독립적으로 떨어져서 형태가 무너집니다.

핵심 원리: "두 점 사이 거리가 원래 길이와 다르면, 두 점을 각각 절반씩 이동시켜 원래 길이로 복원한다." 이 단순한 규칙을 모든 연결에 반복 적용합니다.

왜 반복(iteration)이 필요한가: 한 constraint를 풀면 다른 constraint가 깨집니다. 여러 번 반복하면 전체가 균형점에 수렴합니다. 보통 3~5회면 충분합니다.

Stiffness 조절: correction에 0~1 사이 계수를 곱하면 "유연한" 제약이 돼요. 1.0이면 완전 강체, 0.5면 고무줄처럼!

활용 사례:
- 천(Cloth) 시뮬레이션: 격자형 constraint 네트워크
- 로프/체인: 일렬로 연결된 constraint
- 소프트바디: 삼각형 메시 + constraint
- 래그돌 물리: 관절 = constraint

참고: Coding Train: Soft Body Physics · Tearable Cloth Tutorial · PBD 원논문 (Müller 2006)

1.00
3
0.30
12
8

지금까지: 객체 중심

Object-Centered Approach

  • 각 파티클이 자신의 규칙 보유
  • "나는 어떻게 움직일까?"
  • 개별 행동 → 집단 패턴

이제부터: 공간 중심

Space-Centered Approach

  • 공간에 규칙이 존재
  • "여기선 어느 방향으로?"
  • 파티클은 공간을 따를 뿐
⟳

패러다임 전환: Flow Field

공간 자체에 방향성을 부여하면, 수천 개의 파티클이 자연스럽게 흐른다

발상의 전환: "파티클이 어떻게 움직일까?" → "이 위치에서 어느 방향으로?"

Flow Field: 보이지 않는 바람

Tyler Hobbs, Zach Lieberman 등 유명 아티스트들의 비밀 무기!

공간의 각 지점에 방향(벡터)을 할당. 파티클은 자신의 위치에서 방향을 읽고 따른다.

1. 필드 구조 정의

// 격자 기반 벡터 필드
cols = width / resolution
rows = height / resolution
field[x][y] = noise(x, y) × 2π  // 각도

resolution = 20~30px이 보통 적당해요

2. 파티클에 적용

// 위치에서 방향 읽기
gridX = floor(pos.x / resolution)
gridY = floor(pos.y / resolution)
force = fromAngle(field[gridX][gridY])

현재 위치의 "바람 방향"을 읽는 거예요!

함께 생각해보기: 왜 Perlin Noise를 쓸까?

Math.random()을 쓰면? 인접한 셀의 방향이 완전 무관해서 파티클이 갈팡질팡해요.
Perlin Noise는 Ken Perlin이 1983년에 개발. 영화 <트론>을 위해 만들었어요!
특징: 공간적 연속성 - 가까운 위치는 비슷한 값을 가져서 부드러운 흐름이 만들어져요.

변형 아이디어: noise(x, y, time)으로 3D 노이즈를 쓰면 시간에 따라 필드가 변해요. 살아 숨쉬는 바람!

데모 설명: "Show Vectors"를 켜면 각 셀의 방향이 화살표로 보입니다. 파티클은 자신이 위치한 셀의 화살표 방향으로 힘을 받습니다.

해상도(resolution) 선택:
- 작은 값(10~20px): 세밀한 흐름, 계산 비용 높음
- 큰 값(40~60px): 부드러운 흐름, 성능 좋음
- 일반적으로 20~30px 추천

필드 생성 방법:
- Perlin Noise: 부드러운 자연스러운 흐름
- Simplex Noise: Perlin보다 빠르고 아티팩트 적음
- 수학 함수: sin, cos 조합으로 특정 패턴 생성
- 이미지 기반: 이미지의 밝기/색상을 각도로 변환

시간 변화: noise(x, y, time)을 사용하면 필드가 시간에 따라 변합니다. 살아있는 바람처럼!

프로 팁: noise 값에 scale 계수를 곱하면 소용돌이 크기가 달라져요. noise(x × 0.01, y × 0.01)은 큰 소용돌이, noise(x × 0.1, y × 0.1)은 작은 소용돌이!

참고: Coding Train: Flow Fields · Tyler Hobbs: Flow Fields · Perlin Noise (Wikipedia)

25
0.10
0.30
0.20
0.10

Curl Noise = Organic Motion

회전(rotation)이 들어가면 생명이 생긴다. 연기, 물, 불꽃의 비밀.

벡터 미적분이 나오지만 걱정 마세요, 같이 천천히 이해해봐요!

일반 Noise → Gradient 문제

  • 각 위치에서 스칼라 값 반환
  • Gradient = "높은 곳 → 낮은 곳" 방향
  • 파티클이 "계곡"으로 모임 (수렴)
  • 뭉치거나 사라지는 비현실적 움직임

물이 산에서 계곡으로 모이듯, 파티클이 한 곳에 쌓여요

Curl Noise 해결

  • Gradient를 90도 회전!
  • 등고선을 따라 흐름 (발산 없음)
  • 유체처럼 자연스럽게 순환
  • 절대 뭉치거나 발산하지 않음

물이 계곡이 아닌 등고선을 따라 흐르는 것처럼!

// 2D Curl Noise - 핵심 공식 (gradient의 90도 회전!)
eps = 0.0001  // 미분용 작은 값
n1 = noise(x, y)
n2 = noise(x, y + eps)
n3 = noise(x + eps, y)
// Gradient = (∂n/∂x, ∂n/∂y) → 90° 회전 = (∂n/∂y, -∂n/∂x)
curl.x = (n2 - n1) / eps  // ∂n/∂y
curl.y = -(n3 - n1) / eps  // -∂n/∂x

함께 이해하기: 왜 "Curl"이고 왜 "발산이 없을까"?

Curl은 벡터 미적분에서 "회전량"을 측정해요. 물에 작은 바람개비를 넣으면 회전하는 정도!
Divergence-free의 의미: ∇·F = 0 → "들어오는 양 = 나가는 양". 물이 솟아나거나 빠지는 곳 없이 그냥 순환!
수학적으로: curl(gradient) = 0이 항상 성립. 우리는 gradient를 회전시켜서 발산을 없앤 거예요!

영화 VFX의 비밀: 아바타, 인터스텔라의 연기/구름 시뮬레이션도 Curl Noise 기반! 2007년 Bridson의 SIGGRAPH 논문이 업계 표준이 됐어요.

왜 Curl인가: 벡터 미적분학에서 curl은 "회전"을 나타냅니다. 2D에서는 스칼라 필드의 gradient를 90도 회전시킨 것과 같습니다.

divergence-free의 의미: 벡터장의 발산(divergence)이 0이면 "소스"나 "싱크"가 없습니다. 물이 한 곳에서 솟아나거나 빠져나가지 않고 그냥 흐릅니다.

직관적 이해: 지형도를 상상해보세요. Gradient는 "가장 가파른 내리막 방향"이에요. Curl은 그걸 90도 돌려서 "등고선 방향"으로 만든 거예요. 그래서 높이가 변하지 않고 순환만 해요!

슬라이더 실험:
- Scale ↑: 더 큰 소용돌이, 느린 변화
- Scale ↓: 작고 촘촘한 소용돌이
- Intensity ↑: 더 빠른 움직임
- Intensity ↓: 부드럽고 느린 흐름

실무 활용: 연기, 안개, 물결, 오로라, 추상적 배경 애니메이션에 필수. Three.js, Unity, Unreal 모두 Curl Noise 지원.

참고: Curl-Noise (Bridson 원논문) · Sebastian Lague: Procedural Landmass · Bit-101: Curl Noise 설명

Scale
Intensity

Easing: 물리가 필요 없을 때

최소 비용으로 자연스러운 움직임 만들기

Linear: t
Smoothstep: t²(3-2t)

대표적인 Easing 함수

linear(t) = t
smoothstep(t) = t² × (3 - 2t)
easeOutQuad(t) = 1 - (1-t)²
easeOutElastic(t) = sin(-13π/2 × (t+1)) × 2^(-10t) + 1

언제 사용하나?

  • 시작/끝 지점이 명확할 때
  • UI 전환, 페이드 인/아웃
  • 정확한 타이밍 제어 필요
  • 물리 시뮬 오버헤드가 과할 때

Easing vs Spring — Easing은 "정해진 시간 내 완료", Spring은 "목표에 도달할 때까지"

유용한 리소스

easings.net
30+ easing 함수 시각화 및 코드
easings.net →
cubic-bezier.com
CSS cubic-bezier 커스텀 에디터
cubic-bezier.com →

One System, Infinite Variations

지금까지 배운 모든 것을 하나의 시스템에 통합

구조 (Structure)

Verlet Particles
+ Distance Constraints
→ 형태 유지

힘 (Forces)

Gravity + Spring
+ Curl Noise Flow
→ 움직임 생성

변화 (Variation)

파라미터 조절로
완전히 다른 결과
→ 무한 변주

// 통합 시스템의 핵심 루프
for (particle of particles) {
  particle.applyForce(gravity);  // 1. 중력
  particle.applyForce(curlNoise(pos, time));  // 2. 플로우
  particle.applyForce(springToCenter(pos));  // 3. 구심력
  particle.update();  // 4. Verlet 통합
}
for (constraint of constraints) {
  constraint.solve();  // 5. 거리 제약 해결
}

결과물이 아니라 시스템을 만들어라. 슬라이더를 조절해보세요!

데모 가이드: 3개의 슬라이더를 각각 극단적으로 움직여보세요.
- Flow만 최대: 바람에 날리는 깃발
- Gravity만 최대: 무거운 체인
- Spring만 최대: 중심으로 빨려드는 형태
- 세 가지 조합: 각각 다른 "성격"을 가진 생명체

핵심 통찰: 이 데모에서 변경한 코드는 0줄입니다. 파라미터만 바꿨을 뿐. 잘 설계된 시스템은 코드 수정 없이 무한한 변주가 가능합니다.

실무 적용:
- 게임 VFX: 동일 시스템으로 불, 물, 연기, 마법 이펙트
- 웹 인터랙션: 마우스 반응형 배경 애니메이션
- 데이터 시각화: 노드-링크 다이어그램의 물리적 배치
- 제너러티브 아트: 동일 알고리즘, 다른 시드값 = 다른 작품

확장 아이디어: 더 많은 힘 추가 (마찰, 반발력, 자기장), 더 복잡한 구조 (2D 천, 3D 메시), 사용자 상호작용 (터치/마우스로 힘 적용)

Flow
Spring
Gravity

Procedural Art는 완성형이 아니라
계속 변하는 상태다

  • 움직임의 본질은 시간에 따른 변화 규칙
  • 물리 시뮬레이션은 창작 도구로 활용
  • 정확성보다 느낌이 중요
  • 하나의 시스템으로 무한한 변주

Form → Motion → Behavior → System

마무리 멘트: "오늘 배운 것들은 물리학이 아닙니다. 물리학의 아이디어를 빌려온 창작 도구입니다. 정확할 필요 없습니다. '느낌'이 맞으면 됩니다."

청중에게 던질 질문: "여러분이 만들고 싶은 움직임은 어떤 성격인가요? 무겁고 느린? 가볍고 탄성 있는? 유기적이고 흐르는? 오늘 배운 도구들로 그 성격을 코드로 표현해보세요."

다음 스텝 제안:
1. 이 프레젠테이션의 코드를 직접 수정해보기
2. p5.js로 간단한 파티클 시스템 만들기
3. The Nature of Code 책/영상 학습
4. 하루에 작은 실험 하나씩 시도

추천 첫 프로젝트: "마우스를 따라다니는 점 100개" - Particle + Force + Spring만으로 만들 수 있는 가장 간단하면서도 매력적인 인터랙션입니다.

학습 자료 & 다음 단계

Creative Coding 여정을 위한 추천 자료들

필수 도서 & 강의

The Nature of Code
Daniel Shiffman. 물리 기반 크리에이티브 코딩의 바이블. 무료 온라인 버전 제공.
natureofcode.com →
The Coding Train
YouTube 채널. 시각적으로 이해하기 쉬운 코딩 튜토리얼.
thecodingtrain.com →
Generative Design
Benedikt Gross 외. 알고리즘 기반 디자인의 교과서.
generative-gestaltung.de →
Game Programming Patterns
Bob Nystrom. 게임 루프, 상태 패턴 등 구조적 접근법.
gameprogrammingpatterns.com →

라이브러리 & 프레임워크

p5.js
가장 접근하기 쉬운 크리에이티브 코딩 라이브러리. Processing의 JS 버전.
p5js.org →
Three.js
WebGL 기반 3D 그래픽스. 파티클 시스템, 셰이더 지원.
threejs.org →
Matter.js
2D 물리 엔진. 강체, 충돌, 제약조건 시뮬레이션.
brm.io/matter-js →
Cannon.js / Rapier
3D 물리 엔진. Three.js와 함께 사용하기 좋음.
rapier.rs →

영감을 주는 곳들

OpenProcessing
Processing/p5.js 작품 공유 플랫폼. 코드 공개.
openprocessing.org →
Shadertoy
GLSL 셰이더 작품들. 고급 비주얼 기법 학습.
shadertoy.com →
CodePen
웹 기반 코드 실험 플랫폼. Creative Coding 태그 검색.
codepen.io →
#genart / #creativecoding
Twitter/X, Instagram 해시태그. 최신 트렌드와 영감.

입문자 추천 학습 경로:
1. p5.js 공식 튜토리얼 (Get Started)
2. The Coding Train "Nature of Code" 시리즈
3. Nature of Code 책 Chapter 1-4
4. OpenProcessing에서 예제 분석하며 따라하기

중급자 추천:
1. Three.js Journey (Bruno Simon) - 유료지만 최고 퀄리티
2. Shadertoy에서 셰이더 기초 학습
3. Matter.js로 물리 게임 만들기
4. Generative Design 책으로 알고리즘 깊이 파기

커뮤니티 참여: Creative Coding Seoul 밋업, #genart 해시태그, Discord 커뮤니티(Genuary, Creative Coding 등)

01 / 16