핵심 요약
React Three Fiber 9가 4월에 WebGPU 백엔드를 안정 채택. 같은 씬을 WebGL 대비 GPU 사용 40% 감소, 컴퓨트 셰이더로 파티클 100만 개 60fps. Chrome·Edge·Safari 17.4+ 데스크톱은 안정, Android Chrome도 4월부터 기본 활성. iOS Safari는 16.4부터 플래그, 안정은 17.5 이후 권장. 모바일 호환을 위해 WebGL 폴백은 필수.
1. 환경 세팅 — 1분
pnpm create vite my-3d --template react-ts
cd my-3d
pnpm add three@0.175 @react-three/fiber@9 @react-three/drei
pnpm add -D @types/three
2. WebGPU 렌더러로 부팅
import { Canvas } from '@react-three/fiber'
import { WebGPURenderer } from 'three/webgpu'
<Canvas
gl={async (props) => {
const r = new WebGPURenderer(props)
await r.init()
return r
}}
fallback={<div>3D not supported</div>}
>
<Scene />
</Canvas>
3. 기본 씬 — 5분
import { OrbitControls, Environment } from '@react-three/drei'
function Scene() {
return (
<>
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
<mesh rotation={[0.4, 0.3, 0]}>
<torusKnotGeometry args={[1, 0.3, 200, 32]} />
<meshStandardMaterial color="hotpink" metalness={0.4} />
</mesh>
<Environment preset="city" />
<OrbitControls />
</>
)
}
4. WebGL vs WebGPU 실측
| 씬 | WebGL2 | WebGPU | 차이 |
| 구체 1,000개 + PBR | 58fps | 60fps cap | GPU 사용 -32% |
| 파티클 100만(컴퓨트) | 14fps | 60fps | +329% |
| 인스턴스 메시 50K | 42fps | 60fps | +43% |
| 섀도우 + SSAO | 38fps | 54fps | +42% |
5. 컴퓨트 셰이더 — WebGPU의 진짜 무기
import { Fn, instanceIndex, vec3, sin, time } from 'three/tsl'
const positionUpdate = Fn(() => {
const i = instanceIndex
return vec3(
sin(time.mul(0.3).add(i.toFloat().mul(0.1))),
i.toFloat().mod(100).div(100),
0
)
})
// 컴퓨트로 100만 포지션 업데이트
const compute = positionUpdate.compute(1_000_000)
renderer.compute(compute)
6. Drei 헬퍼
| 헬퍼 | 용도 |
| <Environment /> | HDRI 환경광 |
| <Html /> | 3D 안 DOM |
| <Instances /> | 인스턴싱 |
| <useGLTF /> | GLB 로드+캐시 |
| <ContactShadows /> | 가짜 섀도우 |
7. 모바일 호환
| 플랫폼 | WebGPU | 주의 |
| Android Chrome 132+ | 기본 | 저가폰 Mali GPU 컴파일 30s 사례 |
| iOS Safari 17.4~17.5 | 플래그 | 실험적, 폴백 필수 |
| iOS Safari 17.6+ | 기본 | 일부 셰이더 컴파일 실패 보고 |
| 구형 안드로이드 | 없음 | WebGL 폴백 |
8. 흔한 함정
1) await renderer.init()을 빼먹으면 첫 프레임이 검정. 2) WebGPU는 텍스처 포맷이 엄격 — sRGB 변환을 명시. 3) 인스턴스 메시는 useFrame 안에서 instanceMatrix.needsUpdate를 true로. 4) Drei OrbitControls는 makeDefault prop을 줘야 다른 hook들이 인식. 5) Suspense로 useGLTF를 감싸지 않으면 lazy 로드 중 폭발.
참고
- r3f.docs.pmnd.rs
- threejs.org/manual
- github.com/pmndrs/drei
- caniuse.com/webgpu
댓글 0