본문으로 건너뛰기
피드

WebGPU로 브라우저에서 실시간 글로벌 일루미네이션 구현하기 — Surfel 기반 파이프라인

frontend 약 6분
vote
0
댓글
북마크

Surfel(Surface Element) 기반 글로벌 일루미네이션을 WebGPU로 브라우저에서 구현한 프로젝트. 13개 이상의 컴퓨트 패스, 소프트웨어 BVH 레이 트레이싱, MSME 시간적 안정화까지 TypeScript+WGSL 약 3000줄로 60fps 달성.

  • 1

    Surfel로 조명 계산을 스크린 해상도에서 분리해 5만 개로 200만 픽셀 GI 처리

  • 2

    하드웨어 RT 없이 three-mesh-bvh로 BVH 에뮬레이션

  • 3

    가이딩 시스템으로 밝은 방향에 레이를 집중하고 MSME로 시간적 안정화

  • 4

    Radial Depth Atlas + MSM으로 빛 누수 문제 해결

  • 5

    TypeScript+WGSL 3000줄, iPhone 14 Safari에서도 60fps

WebGPU로 브라우저에서 실시간 글로벌 일루미네이션을 구현한 이야기

  • Surfel(Surface Element)이라는 3D 공간의 납작한 디스크를 이용해 웹 브라우저에서 실시간 글로벌 일루미네이션(GI)을 구현한 프로젝트임. 위치·법선·반지름으로 정의되는 surfel로 조명 계산을 스크린 해상도에서 분리해, 5만 개의 surfel만 셰이딩해도 200만 픽셀의 GI를 처리할 수 있다는 게 핵심

  • EA SEED가 SIGGRAPH 21에서 발표한 surfel 기반 GI 기법에서 영감을 받았고, SIGGRAPH 2025 밴쿠버에서 본 "SurfelPlus" 포스터의 "저사양 GPU에서도 풍부한 동적 간접 조명을 실시간으로" 라는 문구가 "저사양 GPU ≈ 웹"이라는 발상으로 이어진 거임

파이프라인: 프레임당 13개 이상의 컴퓨트 패스

1. Surfelization — 지오메트리를 surfel로 변환

  • G-buffer(깊이, 법선, 알베도)를 렌더링한 뒤, 빠진 곳에 surfel을 스폰하고, 기존 surfel과 비교해서 원자적 병렬 경쟁을 거쳐 승자만 살아남는 방식. 프로덕션 수준에서는 공간 데이터 구조 유지·라이프사이클 관리 등 10개 이상의 컴퓨트 패스가 필요함

2. 그리드 — 공간 가속 구조

  • Kajiya 렌더러에서 영감받은 카메라 중심 캐스케이드 3D 공간 인덱스. 가까운 surfel은 정밀한 셀, 먼 surfel은 큰 셀로 관리하는 멀티-레졸루션 구조임
  • 빌드 과정: 셀 카운터 초기화 → 원자적 증가로 셀별 surfel 수 카운트 → prefix-sum 스캔 → atomic decrement 트릭으로 슬로팅. 결과적으로 O(1)로 셀의 surfel 인덱스에 접근 가능
  • 이거 없으면 픽셀마다 512개 surfel을 전부 비교해야 해서 사실상 불가능

3. 레이 트레이싱 — 하드웨어 RT 없이

  • WebGPU에는 하드웨어 레이 트레이싱 지원이 없음. 대신 three-mesh-bvh 라이브러리를 사용해 CPU에서 BVH(Bounding Volume Hierarchy)를 빌드하고 GPU 컴퓨트 셰이더에서 쿼리하는 방식으로 에뮬레이션
  • 머티리얼 샘플링은 2D 배열 텍스처에 모든 디퓨즈 텍스처를 레이어로 쌓고, 삼각형마다 matId를 저장해서 히트 시 (uv, matId)로 샘플링하는 해킹적 접근

4. 가이딩 — 빛이 오는 방향 학습

  • 각 surfel이 반구 위에 8×8(64 bin) 가중치 그리드를 유지함. 레이가 밝은 방향을 발견하면 해당 bin의 가중치를 올리고, 시간이 지나면 밝은 방향으로 레이를 더 많이 쏘는 구조
  • 탐색(exploration)과 활용(exploitation) 균형을 위해 가이딩 확률과 코사인 반구 샘플링을 혼합하고, 혼합 확률밀도함수(mixPdf)로 편향 없는 추정을 유지함
  • 새로 태어난 surfel은 탐색을 많이 하고, 성숙한 surfel은 활용을 많이 하는 설계가 귀여움

5. 시간적 안정성 — MSME

  • 단순 지수 이동 평균(EMA)은 반응이 빠르면 노이즈가 심하고, 안정적이면 느림. MSME(Multi-Scale Mean Estimator)는 장기/단기 두 개의 평균을 추적해, 실제 변화에는 빠르게 반응하되 노이즈에는 과잉반응하지 않음
  • EA SEED의 PICA PICA 파이프라인(Ray Tracing Gems 25장)에서 소개된 알고리즘

6. 빛 누수 해결 — Radial Depth Atlas

  • Surfel이 벽 가장자리에 있으면 반대편으로 빛이 새는 문제가 있음. 각 surfel에 360도 깊이 카메라(4×4 픽셀 타일)를 달아서 주변 지오메트리까지의 거리를 기록하고, Moment Shadow Mapping(MSM)으로 부드러운 가시성 함수를 재구성해 벽 뒤로 빛이 새는 걸 차단

7. Resolve — surfel에서 픽셀로

  • 모든 픽셀에 대해 G-buffer 깊이로 월드 좌표를 계산하고, 그리드에서 주변 surfel을 찾아서 거리·방향·나이·오클루전 가중치를 적용해 최종 색상을 결정

결과와 한계

중요

> 전체 파이프라인이 TypeScript + WGSL 약 3,000줄로 구현됨. 적당한 복잡도의 씬에서 60fps로 동작하고, iPhone 14의 모바일 Safari에서도 Cornell Box 씬이 60fps

  • 한계: Chrome의 스토리지 버퍼 상한이 컴퓨트 패스당 10개라 read-write float 스토리지 텍스처로 우회하는 등 바인딩 한계와 싸워야 했음. Firefox/Safari는 더 많은 바인딩을 지원하지만 float 스토리지 텍스처를 못 씀
  • 하드웨어 RT가 없어서 다수 광원, 동적 지오메트리 지원이 어려움. 현재는 단일 디렉셔널 라이트 + 환경 맵의 정적 지오메트리 디퓨즈 반사만 지원
  • 스페큘러/글로시 반사, 투명도, AO, 이미시브 없음. 그래도 브라우저에서 물리 기반 빛 반사와 시간적 안정성이 돌아가는 것 자체가 "미래에 와 있는" 느낌이라고

WebGPU의 성숙도를 증명하는 프로젝트. 몇 년 전에는 불가능했던 컴퓨트 중심 렌더링 파이프라인이 브라우저에서 돌아간다는 게 인상적

댓글

댓글

댓글을 불러오는 중...

frontend

타입스크립트 7.0, Go 네이티브 포팅으로 빌드가 8~12배 빨라졌다

마이크로소프트가 타입스크립트 7.0을 출시하면서 기존 자바스크립트 기반 구현을 Go로 네이티브 포팅했다. 전체 빌드는 평균 8~12배 빨라졌고, VS코드 빌드는 125.7초에서 10.6초로 줄었으며, 슬랙은 CI 타입 검사 시간을 7.5분에서 1.25분으로 낮췄다.

frontend

타입스크립트 7 공개, 고 포팅으로 빌드가 최대 10배 이상 빨라짐

마이크로소프트가 고(Go)로 네이티브 포팅한 타입스크립트 7을 공개했다. 전체 빌드는 보통 8~12배 빨라지고, VS 코드 코드베이스에서는 125.7초가 10.6초로 줄었으며, 편집기 첫 오류 표시도 17.5초에서 1.3초 미만으로 내려갔다.

frontend

“98% 지원”이 생각보다 별로 안 넉넉한 이유

브라우저 기능 지원률 98%는 얼핏 높아 보이지만, 실제 서비스에서는 2%의 사용자를 깨진 화면 앞에 세우는 숫자일 수 있다는 글이다. 특히 일반 통계와 내 서비스 방문자 분포는 다를 수 있고, 실제 사례로 어떤 사이트는 최신 중첩 CSS 기능 지원 브라우저가 방문자의 약 70%뿐이었다.

frontend

메타, AI가 읽고 쓰는 디자인 시스템 ‘Astryx’ 오픈소스로 공개

메타가 내부 디자인 시스템 Astryx를 오픈소스로 공개했다. React와 StyleX 기반의 150개 이상 접근성 지원 컴포넌트, 디자인 토큰, 테마, 템플릿, CLI를 제공하며, 특히 AI 에이전트가 컴포넌트 구조를 이해하고 UI를 생성·수정할 수 있도록 MCP 서버까지 포함한 점이 핵심이다.

frontend

shadcn/ui, 기본 컴포넌트 라이브러리를 Radix에서 Base UI로 변경

shadcn/ui가 새 프로젝트의 기본 컴포넌트 라이브러리를 Radix가 아니라 Base UI로 바꿨어. Radix 지원은 계속되지만, Base UI가 안정화됐고 주간 다운로드 600만 이상, shadcn/create 신규 프로젝트 선택 비율 2대1이라는 이유로 기본값을 바꾼 거야. 동시에 채팅 UI용 MessageScroller와 관련 컴포넌트, headless 패키지인 @shadcn/react도 공개됐어.