본문으로 건너뛰기

3D 뷰어 안에는 생각보다 많은 것이 들어있습니다

브라우저에서 3D 모델을 보여주는 뷰어, 겉보기엔 단순해 보입니다. 하지만 막상 만들어 보면, 화면 렌더링, 카메라 제어, 조명, 물체 선택, 단면 자르기, 애니메이션 등 17개 이상의 내부 모듈이 서로 맞물려 돌아가야 합니다.

이전 경험에서 배운 것​

이전 직장에서 3D 뷰어를 개발하면서 겪은 문제가 있었습니다. 기능이 하나둘 추가될수록 모듈끼리 서로를 직접 참조하게 되었고, 하나를 고치면 다른 곳이 깨지는 상황이 반복됐습니다.

오픈소스 3dviewer.net의 코드도 참고했는데, 280개 이상의 기능을 한꺼번에 내보내는 구조라 "어디서부터 시작해야 하지?"라는 느낌이 들었습니다.

Voxel3D의 설계​

그래서 Voxel3D는 처음부터 다르게 설계했습니다.

  • 사용하는 쪽에서는 Voxel3D라는 하나의 창구만 알면 됩니다
  • 내부의 17개 모듈은 완전히 감춰져 있어서 직접 건드릴 수 없습니다
  • 모듈끼리 서로를 모르고, 중앙에서 연결해 줍니다
const viewer = new Voxel3D({ container: '#app' });
viewer.loadModel('model.glb');
viewer.selectObject(mesh);

이 3줄 뒤에서는 렌더링, 물체 탐색 가속, 선택 감지, 하이라이트, 트리 구조 동기화가 자동으로 연동됩니다. 하지만 사용하는 사람은 그걸 알 필요가 없습니다.

아키텍처 구조​

┌─────────────────────────────────────────────┐
│ External Consumer │
│ import { Voxel3D } from '...' │
├─────────────────────────────────────────────┤
│ Voxel3D (Facade) │
│ 180+ Public API Methods │
├──────┬──────┬──────┬──────┬──────┬──────────┤
│Scene │Camera│BVH │Select│Clip │ ...17+ │
│Mgr │Mgr │Mgr │Mgr │Mgr │ Managers │
├──────┴──────┴──────┴──────┴──────┴──────────┤
│ LogSystem ErrorSystem EventSystem │
└─────────────────────────────────────────────┘

결국 3D 뷰어를 잘 만드는 건, 3D 기술의 문제이기도 하지만 소프트웨어 설계의 문제이기도 합니다.