SVG Paper Wave

pure SVG · no WebGL · 3D→2D by hand

해설 / How it works ↓
0points
0SVG elements
0FPS
0ms / frame
math 0 · dom 0

어떻게 동작하나 How it works

1 · 곡면 The surface

z(x, t) = A · sin( 2π·x / λ − t·speed·2π )

종이 띠는 x(길이) × y(폭) 격자이고 높이는 x만의 함수입니다. Folded를 켜면 구간 경계에서만 z를 샘플하고 그 사이는 직선으로 이어서, 각 구간이 평평한 면(facet)이 됩니다.

The strip is a grid in x (length) × y (width); height depends on x only. “Folded” samples z only at segment boundaries and interpolates linearly, so each segment is one flat facet.

2 · 회전 Rotation (yaw + tilt)

      ⎡ cosθ  −sinθ  0 ⎤
Rz(θ)=⎢ sinθ   cosθ  0 ⎥   (rotate, 0–360°)
      ⎣  0      0    1 ⎦

      ⎡ 1   0     0   ⎤
Rx(φ)=⎢ 0  cosφ  sinφ ⎥   (tilt, 0° = side, 90° = top)
      ⎣ 0 −sinφ  cosφ ⎦

행렬 라이브러리 없이 계수 8개(a…h)를 프레임당 한 번만 계산하고, 모든 점에 곱셈·덧셈만 적용합니다.

No matrix library: eight coefficients are computed once per frame, then every point costs a handful of multiply-adds.

3 · 투영 Projection

right = x′ = x cosθ − y sinθ
up    = z cosφ + y′ sinφ
depth = y′ cosφ − z sinφ
k  = d / (d + depth)          (d→∞ : 직교)
sx =  right · k · scale
sy = −up    · k · scale       (SVG의 y는 아래쪽)

투영 해부를 켜면 5개 점의 3D 좌표 → 화면 좌표, 바닥 그림자 발자국, sx·sy 두 변을 직접 볼 수 있습니다.

Toggle “projection anatomy” to see five points: world coords → screen coords, floor footprint, and the sx / sy legs.

4 · 화가 알고리즘 Painter's sort

SVG에는 z-buffer가 없고 DOM 순서가 곧 그리기 순서입니다. 그래서 매 프레임 각 셀의 평균 카메라 깊이를 구해 먼 것 → 가까운 것 순으로 정렬하고, 그 순서대로 <path>에 d·fill을 씁니다. 회전할 때마다 순서가 바뀌므로 정렬은 매 프레임 필요합니다. 그림자는 같은 사각형을 바닥(z=0)에 비스듬히 투영해 한 개의 path로 합치고 SVG 블러 필터를 적용합니다.

SVG has no z-buffer — DOM order is paint order. Each frame we sort cells by mean camera depth, far → near, and write them into a pool of <path>s. The shadow is the same quads projected obliquely onto the floor, merged into one path, blurred by an SVG filter.

5 · 언제 WebGL로 넘어가나 When to switch to WebGL

병목은 수학이 아니라 DOM입니다. 요소 수가 늘면 속성 갱신, 스타일 계산, 래스터화가 선형 이상으로 느려집니다. 이 기기에서 Stress test를 돌린 결과:

아직 측정 전 — 패널의 Stress test 를 실행하세요.
not measured yet — run “Stress test” in the panel.
  • 수천 셀 이하, 정적 표현, 벡터 export가 필요 → SVG 유지 (접근성·.svg 저장·CSS 스타일링 장점).
  • 수만 셀 이상, 60fps 필수, 텍스처·실시간 조명·z-buffer가 필요 → WebGL / WebGPU (정점은 GPU, 정렬은 depth test가 처리).
  • 중간 지대 → Canvas 2D로 같은 painter's 루프를 돌리면 DOM 비용만 제거됩니다.

The bottleneck is the DOM, not the math. Stay on SVG for ≤ a few thousand cells and when vector export or CSS styling matter; move to WebGL/WebGPU for tens of thousands of cells, locked 60 fps, or real lighting. Canvas 2D is the middle step — same painter's loop, no DOM cost.