Three.js 프로젝트 세팅과 renderer lifecycle
Three.js를 editor에 붙일 때 첫 문제는 설치가 아니라 lifecycle입니다. canvas를 언제 만들고, 크기를 언제 맞추고, renderer를 언제 정리할지 먼저 정해야 합니다.
renderer를 생성한다
import * as THREE from "three";
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true,
alpha: true
});
VuePress 강의 예제에서는 iframe 안의 canvas를 renderer surface로 보고, editor shell에서는 canvas element만 renderer backend에 넘깁니다.
CSS size와 drawing buffer를 맞춘다
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height, false);
세 번째 인자를 false로 두면 Three.js가 canvas의 CSS style size를 덮어쓰지 않습니다. editor layout은 CSS가 맡고, drawing buffer는 renderer가 맡는 구조가 됩니다.
resize observer로 lifecycle을 묶는다
function attachThreeRenderer(canvas, render) {
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
const ro = new ResizeObserver(([entry]) => {
const rect = entry.contentRect;
const dpr = Math.min(window.devicePixelRatio || 1, 2);
renderer.setPixelRatio(dpr);
renderer.setSize(rect.width, rect.height, false);
render({ width: rect.width, height: rect.height, dpr });
});
ro.observe(canvas);
return {
renderer,
dispose() {
ro.disconnect();
renderer.dispose();
}
};
}
editor shell에서 중요한 것은 canvas 크기 변경, DPR 변경, route 이동, component unmount를 같은 lifecycle로 다루는 것입니다. 그래야 blurry canvas와 남는 GPU resource를 동시에 피할 수 있습니다.
오늘의 핵심
Three.js renderer도 lifecycle이 있습니다. init -> resize -> render -> dispose를 editor shell의 책임과 맞춰야 합니다.