8주차 · 2026-03-02 ~ 08
파티클과 역사(驛舍)
PIC/FLIP 파티클 시스템과 MRT 스테이션 외관을 병렬로 처음 제대로 만들어 낸 주차. Week 7 에서 들은 '단순화' 피드백이 두 결정 모두를 끌고 갔다.
Week 7 의 그룹 컨설테이션에서 가장 많이 돌아온 말은 하나였다. 단순화. 이번 주는 그 말을 두고 토론하는 대신 처음으로 그 말대로 움직여 본 주차였다. 결과적으로 두 가지 일이 일어났다. 기술 실험으로 돌아가고 있던 PIC/FLIP 파티클 시뮬레이션이 프로젝트가 의지하는 실질 시스템으로 만들어졌다. 그리고 방문자가 작업과 처음으로 닿는 순간이 되어야 할 MRT 스테이션 외관이 처음으로 자신의 비주얼 언어를 얻었다.
둘 다 산문으로 길게 설명하는 대신, 이번 주차의 기록은 둘을 직접 만져볼 수 있게 해 둔다. 아래에 삽입된 시스템은 라이브다. 손을 뻗어 건드려 보고, 파라미터를 돌려 보고, 무엇을 만들어 내는지 직접 확인할 수 있다.
PIC/FLIP 이란
PIC/FLIP 은 Particle-In-Cell 과 FLuid Implicit Particle 의 합성어다. 두 개의 오래된 접근을 혼합하는 하이브리드 유체 시뮬레이션 기법이다. PIC 은 세상을 속도가 격자 위에 살고 있는 셀들의 집합으로 본다. FLIP 은 세상을 각자의 상태를 들고 있는 파티클 군집으로 본다. 어느 쪽도 단독으로는 잘 동작하지 않는다. PIC 만 쓰면 격자 셀 평균에 의해 디테일이 사라진다. FLIP 만 쓰면 파티클들이 서로 일관성을 유지할 방법이 없어 노이즈가 쌓인다. 보통 FLIP 95% + PIC 5% 로 블렌드해서, 파티클의 디테일은 지키면서 격자의 부드러움을 빌려 온다.
아래 컴포넌트는 이 블렌드의 라이브 구현이다. 커서를 위에 올리면 힘이 가해진다. 파라미터를 움직이면 유체가 어떻게 다르게 행동하는지 볼 수 있다. 뷰 모드를 전환해 파티클만, 격자만, 블렌드 상태를 차례로 볼 수 있다.
이 기법은 2000년대 극영화 VFX 를 위해 개발되어, 최근 몇 년 사이 실시간용으로 적응되어 왔다. 내 구현은 컴퓨트 셰이더를 통해 GPU 에서 돌아간다. Week 4 에서 네이티브로의 이관이 중요했던 이유가 이것이다. 브라우저 구현은 내 프로젝트가 요구하는 밀도의 시뮬레이션을 감당하지 못했을 것이다.
왜 David Li 인가
내가 출발점으로 삼은 구현은 David Li 의 WebGL 유체 시뮬레이션, github.com/dli/fluid 이다. PIC/FLIP 을 프로젝트로 가져오기로 결정했을 때, 나는 실제로 배울 수 있는 레퍼런스를 찾는 데 며칠을 썼다. 내가 찾을 수 있던 대부분은 가독성보다 정확성을 위해 쓰인 학술 논문이거나, 내가 필요한 규모 근처에도 가지 않는 극영화 VFX 용 오프라인 구현이었다. David Li 의 코드는 내가 찾은 것 중 유일하게 실시간으로 돌아가고, 브라우저 기반이며, 공개되어 있고, “읽히도록” 쓰인 PIC/FLIP 레퍼런스였다.
접근성 이상의 적합함이 있었다. David Li 시뮬레이션의 스케일은 이미 과학 도구가 아닌 인터랙티브 작품에 맞는 범위 안에 있었다. 수백만이 아니라 수만 개의 파티클. 더 중요한 것은, 상호작용 모델이 내 프로젝트의 철학과 거의 정확히 맞아떨어졌다는 점이다. David Li 의 오리지널에서, 유체는 마우스가 움직이지 않는 한 아무것도 하지 않는다. 고요가 고요를 낳는다. 움직임이 반응을 낳는다. 이것은 내가 소리에 대해 원하던 바로 그 원칙이었다. 침묵은 파티클을 가만히 둔다. 소리가 들어와야 파티클이 살아 움직인다. 알고리즘은 단순히 기술적으로 맞았던 것이 아니라, 그 아래의 논리가 이미 내가 가고 싶은 방향을 가리키고 있었다.
그 위에 내가 쌓은 것이 이 프로젝트가 내 것이 되는 지점이다. David Li 의 시뮬레이션은 WebGL 과 JavaScript 로 돌아간다. 나는 코어 알고리즘을 Python 과 ModernGL 의 OpenGL 컴퓨트 셰이더로 포팅했고, 이것이 Week 4 의 네이티브 애플리케이션 이관을 가능하게 했다. 원본은 자기 격자 컨테이너의 여섯 면 벽만 처리한다. 내 것은 AABB 기반 내부 장애물까지 확장되어 파티클이 도시 모델 안의 개별 건물에 반응할 수 있다. Week 7 의 통합 작업이 요구한 것이 바로 이것이다. 원본은 마우스 움직임에서 힘을 읽는다. 내 것은 FFT 패스를 통해 오디오의 주파수 대역에서 힘을 읽어, 베이스·미드·트레블이 각각 파티클 필드를 다른 방식으로 밀어낸다. 코어 루프는 David Li 의 것이다. 그 위에 쌓인 모든 것이 이 프로젝트다.
David Li 의 구현이 레퍼런스가 된 이유
학습할 만한 PIC/FLIP 구현을 찾기 시작했을 때, 나는 뻔한 목록을 따라갔다. 학술 논문은 정밀하지만 실제 애플리케이션을 만드는 사람에게는 도움이 안 된다. Nvidia 의 Flex 와 Houdini 의 FLIP 솔버는 프로덕션 급이지만 폐쇄 소스라, 읽는 글은 있어도 읽을 코드가 없다. SPH 튜토리얼은 존재하지만 SPH 는 다른 방법이고 다른 아티팩트를 만든다. 내가 필요했던 것은 실시간으로 돌고, 시각적으로 설득력 있으며, 읽히는 소스코드였다. 그 조건이 목록을 매우 빠르게 줄여 주었다. 내가 계속 돌아가게 된 것은 github.com/dli/fluid 에 공개된 David Li 의 WebGL 유체 구현이었다.
내가 다른 선택지보다 이것을 고른 이유는 세 가지였다. 첫째, 브라우저에서 돌아간다는 점. 즉, 무엇을 포팅하기로 결심하기 전에 작동하는 모습을 직접 볼 수 있었다. 페이지를 열고 유체가 어떻게 움직이는지 보고, 파라미터를 바꿔 보고, 이 품질이 프로젝트에 맞는지 스스로 판단할 수 있었다. 내가 찾은 다른 구현들 대부분은 뭔가를 컴파일하거나 연구 환경을 띄워야 했다. 둘째, 코드 자체가 읽혔다. David Li 는 시뮬레이터를 물리와 렌더링이 분리되도록 쓰는 방식으로 작성했고, 덕분에 나는 WebGL 을 동시에 이해하지 않고도 각 부분이 무엇을 하는지 이해할 수 있었다. 셋째, 구현에 충분한 문서가 있어서 원래 의도를 추측하지 않고도 구조를 Python 과 ModernGL 로 옮길 수 있었다.
코드를 쓰기 시작하면서야 분명해진 더 깊은 이유는 그 아래의 멘탈 모델이었다. David Li 의 유체는 혼자서는 아무것도 하지 않는다. 마우스가 움직이지 않으면 힘이 없다. 파티클을 흔드는 것이 없으면 파티클은 가라앉는다. 유체는 자기 바깥의 무엇이 그것에 작용할 때에만 반응한다. 이것이 내 프로젝트가 돌아가는 원리 그대로다. 유체에 작용하는 것이 오디오다. 조용한 오디오는 정지한 파티클을 뜻한다. 큰 오디오는 반응을 뜻한다. 다른 원리 위에 시스템을 만들 수도 있었겠지만, 그럴 필요가 없었다. David Li 의 원리가 이미 옳은 원리였기 때문이다. AABB 건물 경계, 오디오 힘 매핑, 수십만 개 파티클까지의 스케일 확장은 내 연장이지만, “자극에 의해 움직인다” 는 코어 철학은 그의 작업에서 왔다.
왜 파티클인가
여기서 정당하게 던질 수 있는 질문 하나. 왜 프로젝트 전체가 파티클을 중심으로 만들어졌는가. 소리는 파티클처럼 생기지 않았다. 도시도 파티클처럼 생기지 않았다. 외부에서 보면 이 선택은 당연하지 않고, 학위논문은 부분적으로만 설명한다. 더 명확한 답은 파티클이 다른 어떤 비주얼 형식도 하지 못하는 일을 해낼 수 있다는 것을 직접 보는 데에서 나온다.
세 가지 대비가 작동한다. 각각이 이 선택의 한 가지 이유다.
왜 비주얼의 주인공이 파티클인가
소리 ↔ 파티클
소리는 연속적인 신호다. 파티클은 독립된 수천 개의 단위다. 연속 신호를 이산 필드 바로 옆에 두는 것이 연결을 읽히게 만든다. 파가 올라가는 것을 눈이 보고, 파티클이 움직이는 것을 눈이 본다. 설명 없이 지각적 연결이 만들어진다.
지오메트리 ↔ 흐름
도시의 지오메트리는 고정되어 있다. 건축은 움직이지 않는다. 파티클은 끊임없이 움직인다. 두 층이 같은 공간에 공존하는 것이 장소를 연출된 것이 아니라 살아 있는 것처럼 느껴지게 한다. 건물은 경계를 잡고, 파티클이 그 사이의 공기를 채운다.
개별 ↔ 집합
하나의 소리 이벤트는 작다. 그러나 그 사건이 일어나는 순간 수천 개의 파티클이 동시에 반응한다. 반응의 규모 자체가 감각의 일부다. 단일한 도형이 움직이는 것은 장소가 반응한다는 감각을 주지 않는다. 집합적 반응은 그것을 준다.
대비는 장식이 아니다. 각각이 구체적인 어떤 것에 답한다. 소리는 연속적이며 분명히 읽히기 위해 옆에 이산적인 비주얼 형식이 필요하다. 도시의 지오메트리는 정적이며 공간이 살아 있다고 느껴지기 위해 옆에 움직이는 무엇이 있어야 한다. 하나의 오디오 이벤트가 하나의 비주얼 이벤트보다 크게 느껴져야 한다. 그래서 수천 개의 파티클이 함께 반응하는 순간이, 단일 도형의 움직임으로는 담을 수 없는 크기를 담아낸다.
파티클이 주인공인 이유는, 이렇게 움직일 수 있는 비주얼 형식이 내가 찾은 것 중 이것뿐이었기 때문이다.
MRT 스테이션 외관
지난 주의 “단순화” 피드백에는 분명한 함의가 있었다. 다른 어떤 일이 벌어지기 전에 방문자가 먼저 착지해 무엇이 작업인지 이해할, 애매하지 않은 단일 진입점이 필요하다. 그 아래의 복잡도 전부를 보이기 전에. 싱가포르의 논리 안에서 그 장소는 MRT 다. 도시를 방문하는 모든 사람이 역을 통과한다. 역은 배경이 아니다. 모든 지구(地區) 의 문턱이다.
그래서 이번 주에 나는 외관을 MRT 스테이션으로 만들었다. 문자 그대로의 재현이 아니라, 재해석으로서.
1단계 · 모델링
블렌더 안의 날것 그대로의 아키텍처 블록아웃. 텍스처 없는 볼륨, 기본 조명, 기본 지오메트리. 출발점은 표면이 아니라 공간 구조 그 자체.
스테이션을 홀로그램 언어 쪽으로 밀어낸 결정은 의도적이었다. 부기스 MRT 의 충실한 재현은 시뮬레이션이 되었을 것이고, 이 프로젝트는 시뮬레이션이 아니다. 홀로그램 언어는 두 가지를 동시에 담는다. 스테이션으로 읽힌다, 방문자가 어떤 종류의 공간에 들어왔는지 알도록. 동시에 완전히 실제는 아닌 것으로 읽힌다, 방문자가 들어가고 있는 것이 싱가포르 그 자체가 아니라 싱가포르의 소리에 대한 작업이라는 사실을 알려주기 위해. 문턱은 공간적이면서 동시에 시각적이다.
아래 추가 스크린샷은 초기 모델링 패스에서 최종 홀로그램 적용까지 외관 작업의 전체 호(弧) 와, 홀로그램 언어가 스테이션을 넘어 화면 위의 다른 요소들로 어떻게 이어졌는지를 보여 준다.
최종 결과 · 주차 마감 상태