0biglife.

GPU 파티클 플로우

webgl

  • WebGL2
  • GPGPU
  • 파티클
  • ZIP 다운로드

코드

1<!DOCTYPE html>
2<html lang="ko">
3  <head>
4    <meta charset="UTF-8" />
5    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6    <title>GPU 파티클 플로우</title>
7    <link rel="stylesheet" href="./style.css" />
8  </head>
9  <body>
10    <canvas id="gl">GPGPU 입자 흐름 시뮬레이션</canvas>
11    <p id="fallback"></p>
12    <script src="./script.js"></script>
13  </body>
14</html>
15

아이디어

입자 하나하나를 CPU가 아니라 GPU 텍스처에 담는다. 256×256 부동소수점 텍스처의 각 텍셀이 입자 한 개의 위치·수명·시드를 저장하고, 매 프레임 시뮬레이션 셰이더가 텍스처 전체를 한 번에 갱신한다 — 6만 5천 개가 동시에.

핵심 기법

두 장의 텍스처를 번갈아 읽고 쓰는 핑퐁(ping-pong) FBO가 상태를 이어간다. 흐름은 스칼라 노이즈의 회전(curl)으로 만들어, 발산이 없는 — 입자가 뭉치거나 흩어지지 않고 매끄럽게 도는 — 벡터장이다.

1vec2 curl(vec2 p) {
2  float e = 0.009;
3  float dx = potential(p + vec2(e, 0.0)) - potential(p - vec2(e, 0.0));
4  float dy = potential(p + vec2(0.0, e)) - potential(p - vec2(0.0, e));
5  return vec2(dy, -dx) / (2.0 * e);
6}

렌더 패스는 texelFetch로 입자 텍스처를 직접 읽어 6만 5천 개의 점을 가산 합성으로 그린다. 겹칠수록 빛이 모인다.

인터랙션

커서 주변에는 접선 방향 힘이 더해져 입자 떼가 빨려들며 회오리친다. WebGL2와 부동소수점 렌더 타깃이 필요하다.

Index

아이디어핵심 기법인터랙션