React Three Fiber와 WebGPU로 구현한 모듈형 3D 건축 편집기
React Three Fiber·WebGPU 기반으로 노드-스토어·시스템 패턴을 적용한 모듈형 3D 건축 편집기이다.
TL;DR
Pascal Editor는 React Three Fiber와 WebGPU를 기반으로 한 모듈형 3D 건축 편집기로, 노드 중심의 데이터 모델과 패키지별 Zustand 스토어를 사용해 상태를 관리하고 dirty node 집합을 통해 변경된 노드만 렌더 루프에서 재계산한다. NodeRenderer와 sceneRegistry는 노드 ID를 Object3D에 매핑하여 시스템이 useFrame에서 직접 객체를 업데이트하도록 하므로 트리 전체 순회 비용을 회피한다. 플러그인 매니페스트로 노드 스키마·렌더러·툴·패널을 런타임에 확장할 수 있어 외부 확장과 재사용이 용이하며 bun 기반 개발 워크플로와 turborepo monorepo 구조로 빠른 개발 루프와 패키지 단위 배포를 지원한다. 다만 WebGPU 지원 여부와 브라우저 호환성, 프로젝트 전체를 다루는 모노레포 복잡도가 도입 시 검토 포인트로 남는다.
주요 기능
- 렌더링과 편집을 분리하여 뷰어와 에디터를 독립적으로 구성하고 필요에 따라 Viewer를 확장할 수 있다. 이 구조는 @pascal-app/viewer가 기본 카메라·컨트롤·후처리를 제공하고 @pascal-app/editor가 상호작용 도구와 패널을 추가하는 방식으로 구현되어 있다. 패키지별 Zustand 스토어로 상태를 분리하여 의존성 혼선을 줄이고 패키지 단위 테스트와 재사용이 용이하다.
- 변경된 노드만 재계산하는 dirty node 패턴을 사용하여 렌더 루프 오버헤드를 줄인다. 노드가 변경되면 useScene 스토어가 해당 id를 dirtyNodes에 추가하고 useFrame 기반 시스템이 그 항목만 업데이트한 뒤 플래그를 제거하는 방식으로 동작한다. 이로 인해 대규모 씬에서도 불필요한 지오메트리 재생성을 피할 수 있다.
- 플러그인 기반 노드 확장성을 제공하여 외부 플러그인이 노드 스키마, 렌더러, 툴, 패널을 공급할 수 있다. 플러그인은 loadPlugin API로 런타임에 로드되며 내장 플러그인과 동일한 매니페스트 형식을 사용하므로 호환성이 유지된다. 이 구조는 맞춤형 노드 타입과 에디터 확장을 손쉽게 통합하게 한다.
어떻게 동작하는가
뷰어는 React Three Fiber와 WebGPU 기반 렌더러로 장면을 GPU로 렌더링하고, 각 노드 타입별로 NodeRenderer 컴포넌트를 통해 Three.js 객체를 생성하여 sceneRegistry에 등록한다. 상태 변경은 패키지별 Zustand 스토어에서 관리되며 노드 생성·수정·삭제 시 해당 노드가 dirtyNodes에 추가되어 useFrame 훅으로 실행되는 시스템이 해당 노드의 지오메트리를 재계산한다. 플러그인 시스템은 노드 스키마와 렌더러를 런타임에 로드하여 에디터 기능을 확장하는 방식으로 작동한다.
해결 문제
대형 3D 건축 씬을 인터랙티브하게 편집하면서 전체 씬 재계산 비용을 최소화하는 문제를 해결한다. 상태를 평면 레코드로 유지하고 dirty node 집합을 통해 변경된 항목만 재계산함으로써 렌더 루프에서 불필요한 지오메트리 재생성을 방지한다. 또한 패키지 분리와 플러그인 매니페스트로 노드 타입 확장과 재사용을 단순화하여 커스텀 에셋과 툴을 통합할 수 있다.
지금 주목받는 이유
React Three Fiber와 WebGPU 조합으로 브라우저 기반 실시간 3D 편집 환경을 구현하여 성능과 인터랙티브성을 동시에 확보했기 때문에 주목받고 있다. 또한 모듈형 monorepo 구조와 플러그인 확장성으로 커스텀 에디터를 구성하기 쉬운 점이 사용자의 관심을 끌고 있다. 빌트인 노드 및 예제 플러그인으로 실무 적용 실습이 빠르게 가능한 점도 채택 요인이다.
차별점
- 렌더러와 편집기를 패키지 수준으로 분리하여 뷰어만 임베드하거나 에디터를 호스트 앱으로 구성할 수 있다. 이 분리는 런타임 경량화와 UI 커스터마이즈를 동시에 가능하게 하며 패키지별 책임이 명확하다. 따라서 특정 사용 사례에서 불필요한 UI 코드 로드를 피할 수 있다.
- dirty node 처리와 sceneRegistry 매핑을 결합하여 변경 확인과 3D 객체 접근을 상수 시간에 수행한다. Systems는 dirtyNodes 집합을 순회하며 sceneRegistry에서 Object3D를 직접 검색하므로 트리 전체 순회에 따른 비용이 발생하지 않는다. 이 접근은 실시간 편집 응답성을 유지하는 데 유리하다.
- 플러그인 매니페스트를 통해 노드 스키마·렌더러·툴·패널을 동일한 방식으로 등록하므로 외부 플러그인 호환성이 보장된다. 내부 API를 별도로 노출하지 않고도 플러그인이 에디터 확장을 제공할 수 있어 유지보수와 버전 호환성이 향상된다. 예제 플러그인(plugin-trees)이 작동 예시로 제공되어 시작점을 제공한다.
사용 사례
- 건축 및 인테리어 프로토타이핑에서 실시간으로 벽, 슬래브, 지붕, 아이템을 배치하고 컷아웃을 생성하여 설계 반복 속도를 높일 수 있다. 편집 도구와 Zone/Item 배치 로직, spatialGridManager의 배치 검증 기능을 통해 물리적 간섭을 검사하며 배치 규칙을 즉시 확인할 수 있다. 플러그인으로 커스텀 가구나 절차적 요소를 추가하면 설계 라이브러리를 확장할 수 있다.
- 웹 기반 제품으로서 3D 뷰어만 임베딩해 모델 확인 및 시각화를 제공하거나 전체 에디터를 호스팅하여 사용자 편집 기능을 제공하는 두 가지 배포 형태로 활용할 수 있다. Viewer는 기본 카메라·컨트롤·포스트프로세싱을 제공하므로 단순 뷰어로 빠르게 임베드 가능하다. 에디터 앱은 Next.js 호스트를 통해 완전한 편집 워크플로를 제공한다.
- 교육용·데모용으로 모듈형 플러그인 아키텍처를 이용해 노드 타입과 툴을 단계적으로 확장하는 실습 환경을 구성할 수 있다. 예제 플러그인에서 절차적 요소와 프리셋 패널을 참고하여 학습 곡선을 단축할 수 있다. 개발자는 플러그인 매니페스트를 복제하여 자체 도메인 노드를 빠르게 추가할 수 있다.
시작하기
루트 디렉터리에서 bun install로依存성을 설치한 뒤 bun dev를 실행하면 monorepo의 모든 패키지를 빌드하고 Next.js 기반 에디터 개발 서버가 실행된다. 퍼블리시된 패키를 로컬에서 사용하려면 npm install로 @pascal-app/core, @pascal-app/viewer, @pascal-app/editor, @pascal-app/nodes를 설치하고 loadPlugin(builtinPlugin)를 호출하여 빌트인 노드를 로드한 뒤 Viewer를 마운트하면 기본 기능을 이용할 수 있다. 배포 빌드는 turbo build 명령으로 전체 패키지를 빌드하거나 --filter 옵션으로 특정 패키지만 빌드한 다음 npm publish로 퍼블리시한다.
요구사항
- 개발 환경은 Node 생태계 대신 bun을 권장하며 루트에서 bun dev를 실행해야 패키지 핫 리로드가 정상 동작한다.
- 브라우저에서 WebGPU를 지원해야 WebGPU 렌더러의 가속 이점을 얻을 수 있으며, 지원되지 않으면 대체 렌더러가 필요할 수 있다.
- 프로젝트는 React 19와 Next.js 16을 사용하므로 해당 런타임과 호환되는 개발 도구 및 브라우저 환경이 필요하다.
이미지 분석
20.1k
Stars
2.6k
Forks
+214
Trending
57
조회수
관련 토론
아직 관련 토론이 없습니다.
댓글
댓글을 작성하려면 로그인이 필요합니다.