Three.js를 WebGL renderer로 쓰는 기준
앞에서는 WebGL을 직접 다뤘습니다. 이제 같은 editor renderer 문제를 Three.js로 풀어봅니다. 목표는 Three.js에 editor core를 맡기는 것이 아니라, Three.js를 WebGL backend로 쓰는 기준을 세우는 것입니다.
raw WebGL과 Three.js adapter의 차이
Three.js를 쓰더라도 editor core는 같은 snapshot을 넘깁니다. 달라지는 것은 backend가 snapshot을 픽셀로 바꾸는 방식입니다.
type RendererBackend = {
mount(canvas: HTMLCanvasElement): void;
render(snapshot: EditorSnapshot): void;
dispose(): void;
};
class ThreeRendererBackend implements RendererBackend {
mount(canvas) {
this.renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
this.scene = new THREE.Scene();
this.camera = new THREE.OrthographicCamera();
this.objectsByNodeId = new Map();
}
render(snapshot) {
syncCamera(this.camera, snapshot.camera);
syncSceneObjects(this.scene, this.objectsByNodeId, snapshot.scene.nodes);
this.renderer.render(this.scene, this.camera);
}
dispose() {
disposeSceneResources(this.scene);
this.renderer.dispose();
}
}
핵심은 EditorSnapshot이 THREE.Mesh를 모른다는 점입니다. Three.js는 renderer backend 안에서만 사용됩니다.
Three.js가 대신해주는 것
Three.js는 WebGL context, shader program, buffer, render state, camera projection을 하나의 렌더러 경험으로 묶어줍니다.
raw WebGL: context -> shader -> buffer -> draw
Three.js: Scene -> Object3D -> Material -> Renderer
CSS만 하던 사람에게는 처음부터 모든 WebGL 상태를 직접 관리하는 것보다, Three.js의 구조를 통해 GPU renderer의 구성 요소를 읽는 편이 더 빠를 수 있습니다.
그래도 editor core는 분리한다
문서 상태를 THREE.Mesh로 직접 저장하면 renderer를 바꾸기 어렵습니다. editor document는 여전히 renderer-independent 모델로 둡니다.
editor node
-> Three.js adapter
-> THREE.Mesh
이 구조를 지키면 나중에 raw WebGL, WebGPU, Canvas fallback을 붙여도 command model과 저장 포맷은 그대로 남습니다.
오늘의 핵심
Three.js는 WebGL을 숨기는 도구가 아니라, WebGL renderer를 더 높은 추상화에서 구성해보는 도구입니다.