Three.js, 구원자의 등장.

392025년 08월 22일4

WebGL은 강력했다. 개발자에게 GPU를 직접 제어할 수 있는, 전례 없는 힘을 주었다. 하지만 그 힘에는 대가가 따랐다. ‘최초의 삼각형’을 그리는 데에만 수십 줄의 코드가 필요하다는 사실이 보여주듯, WebGL은 너무나도 복잡하고 장황했다.

대부분의 웹 개발자들은 3D 그래픽스의 깊은 원리보다는, ‘화면에 3D 큐브를 띄우고 회전시키는’ 빠른 결과를 원했다. 하지만 WebGL의 저수준 API는 그들에게 너무나 높은 벽이었다.

  • 장면 관리는 어떻게 하지?
  • 카메라와 조명은 어떻게 설정해야 하나?
  • 복잡한 3D 모델 파일(OBJ, FBX 등)은 어떻게 불러와야 할까?
  • 행렬 계산은 너무 어렵고 귀찮다.

이러한 불만과 요구사항이 쌓여갈 무렵, 커뮤니티에서 한 명의 구원자가 등장했다. 스페인 출신의 개발자, 리카르도 카베요 몬테로(Ricardo Cabello Montero), 온라인에서는 미스터 두브(Mr.doob) 라는 닉네임으로 더 잘 알려진 인물이었다.

그는 원래 플래시(Flash) 액션스크립트 3D 라이브러리인 ‘Papervision3D’의 핵심 개발자 중 한 명이었다. 플래시의 시대가 저물고 WebGL의 시대가 열리는 것을 직감한 그는, 자신이 가졌던 3D 그래픽스에 대한 깊은 이해와 노하우를 바탕으로 새로운 프로젝트를 시작했다.

그의 목표는 명확했다. WebGL의 복잡함을 추상화하여, 개발자들이 더 쉽고 직관적으로 3D 콘텐츠를 만들 수 있는 고수준의 라이브러리를 만드는 것.

그렇게 탄생한 것이 바로 ‘Three.js’ 였다.

Three.js는 WebGL의 복잡한 렌더링 파이프라인을 아름답게 포장했다. 개발자들은 더 이상 버퍼를 생성하고, 셰이더를 컴파일하고, attribute와 uniform을 직접 연결하는 고통스러운 과정을 겪을 필요가 없었다. 대신, 훨씬 더 직관적인 개념들을 다루게 되었다.

  1. 장면 (Scene): 모든 3D 객체가 담길 가상의 공간. const scene = new THREE.Scene(); 한 줄이면 충분했다.

  2. 카메라 (Camera): 장면을 바라보는 시점. 원근감을 표현하는 PerspectiveCamera나, 2D 게임처럼 평평하게 보이는 OrthographicCamera를 선택할 수 있었다.

  3. 렌더러 (Renderer): 장면과 카메라 정보를 바탕으로, 실제로 <canvas>에 그림을 그리는 주체. const renderer = new THREE.WebGLRenderer(); 로 생성했다.

  4. 기하학 (Geometry) & 재질 (Material): 3D 객체의 형태(정점 데이터)와 표면의 모습(색상, 질감). Three.js는 BoxGeometry(상자), SphereGeometry(구), PlaneGeometry(평면) 등 다양한 기본 도형과 MeshBasicMaterial(단색), MeshLambertMaterial(음영), MeshPhongMaterial(반사광) 등 여러 재질을 미리 제공했다.

  5. 메시 (Mesh): 기하학과 재질을 합쳐 만든 최종 3D 객체. const cube = new THREE.Mesh(geometry, material); 처럼 만들고, scene.add(cube); 로 장면에 추가했다.

이 모든 것을 사용하면, ‘회전하는 큐브’를 만드는 코드는 놀랍도록 간결해졌다.

// Three.js 코드
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

function animate() {
    requestAnimationFrame(animate);
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;
    renderer.render(scene, camera);
}
animate();

수십 줄의 순수 WebGL 코드가 단 몇 줄의 직관적인 Three.js 코드로 압축된 것이다.
Three.js의 등장은 WebGL 생태계에 가히 폭발적인 변화를 가져왔다.
그래픽스 전문가가 아니었던 수많은 웹 개발자들이 비로소 3D의 세계에 발을 들일 수 있게 되었다. 디자이너, 아티스트, 데이터 과학자들까지 Three.js를 이용해 자신들의 아이디어를 웹에서 3D로 구현하기 시작했다.

워킹 그룹이 ‘WebGL API에 수학 라이브러리를 포함하지 않기로’ 한 결정이 얼마나 현명했는지를 증명하는 순간이었다. 표준은 강력한 기반만 제공했고, 커뮤니티의 천재가 그 위에서 모든 개발자를 위한 아름다운 집을 지어 올린 것이다.

Three.js는 WebGL의 대중화를 이끈 일등공신이 되었다. 블라디미르가 처음 꿈꿨던 ‘누구나 쉽게 접근하는 3D 웹’은, 리카르도라는 또 다른 천재의 손을 거쳐 비로소 완성되고 있었다.