Three.js 시작하기

소개

저의 실험Three.js를 사용해 봤는데, 브라우저에서 3D를 사용할 때 발생하는 골칫거리를 줄이는 데 굉장히 도움이 되었습니다. 이를 통해 카메라, 객체, 조명, 재료 등을 만들 수 있으며 렌더기를 선택할 수 있습니다. 따라서 HTML 5의 캔버스, WebGL, SVG 중 무엇을 사용하여 장면을 그릴지 결정할 수 있습니다. 그리고 그것은 오픈소스이기 때문에 프로젝트에 참여할 수도 있습니다. 하지만 지금은 이것을 엔진으로 사용하여 제가 배운 내용에 집중하고 몇 가지 기본사항을 말씀드리겠습니다.

Three.js의 뛰어난 기능을 제공하는 데 어려움이 있을 수도 있습니다. 일반적으로 예시, 리버스 엔지니어링 및 특정 기능을 찾고 때로는 GitHub를 통해 질문하는 데 꽤 많은 시간을 할애해야 합니다. 궁금한 점이 있으시다면 Doob 선생님AlteredQualia가 굉장히 도움이 되는 것 같네요.

1. 기본사항

여러분은 적어도 3D에 대한 지식을 갖추고 있으며 자바스크립트를 능숙하게 다룰 수 있다고 가정합니다. 잘 모른다면 혼란스러울 수 있으므로 이 항목을 사용해 보기 전에 조금 익혀 두는 것이 좋습니다.

3D 세계에는 다음과 같은 항목이 있으며, 이러한 항목을 만드는 과정을 안내해 드리겠습니다.

  1. 장면
  2. 렌더기
  3. 카메라
  4. 물체 1~2개 (소재 포함)

물론 멋진 작업을 할 수 있습니다. 계속해서 브라우저에서 3D로 실험해 보시기 바랍니다.

2. 지원

브라우저 지원에 관한 간단한 참고사항입니다. 제 경험상 Google의 Chrome 브라우저는 지원되는 렌더기와 기본 JavaScript 엔진의 속도 측면에서 사용하기에 가장 적합한 브라우저입니다. Chrome은 캔버스, WebGL, SVG를 지원하며 엄청나게 빠릅니다. Firefox는 2번째로, 버전 4가 나왔습니다. JavaScript 엔진은 Chrome보다 터치 속도가 느린 것처럼 보이지만, 렌더링 기술 지원은 훌륭합니다. Opera 및 Safari는 WebGL 지원을 추가하는 과정에 있지만 현재 버전에서는 캔버스만 지원합니다. Internet Explorer (버전 9 이상)는 캔버스 렌더링만 지원하며 Microsoft에서 WebGL 기능을 추가할 계획은 전혀 듣지 못했습니다.

3. 장면 설정

모든 렌더링 기술을 지원하는 브라우저를 선택했고 캔버스 또는 WebGL이 보다 표준적인 옵션이므로 렌더링하려고 한다고 가정합니다. 캔버스는 WebGL보다 더 광범위하게 지원되지만 WebGL은 그래픽 카드의 GPU에서 실행되므로 CPU가 물리학이나 사용자 상호작용과 같이 렌더링되지 않는 다른 작업에 집중할 수 있습니다.

선택한 렌더기와 관계없이 JavaScript는 성능을 위해 최적화되어야 합니다. 3D는 브라우저에서 가벼운 작업이 아니며 3D도 가능하다는 것이 좋습니다. 따라서 코드에서 병목 현상의 위치를 파악하고 가능한 한 제거해야 합니다.

따라서 다운로드하고 HTML 파일에 third.js를 포함했다는 가정하에 장면을 설정하려면 어떻게 해야 할까요? 다음과 같습니다.

// set the scene size
var WIDTH = 400,
HEIGHT = 300;

// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;

// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');

// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
                VIEW_ANGLE,
                ASPECT,
                NEAR,
                FAR );

var scene = new THREE.Scene();

// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;

// start the renderer
renderer.setSize(WIDTH, HEIGHT);

// attach the render-supplied DOM element
$container.append(renderer.domElement);

그리 어렵지 않습니다.

4. 메시 만들기

장면, 카메라, 렌더러 (샘플 코드에서 WebGL을 선택함)가 있지만 실제로 그릴 것은 없습니다. Three.js는 몇 가지 표준 파일 형식 로드를 지원합니다. 이는 Blender, Maya, Cinema4D 등의 모델을 출력하는 경우에 유용합니다. 작업을 간단하게 하기 위해 여기서 시작하도록 하겠습니다. 프리미티브에 관해 이야기하겠습니다. 프리미티브는 구, 평면, 정육면체, 원기둥과 같이 비교적 기본적인 메시인 기하학적 메시입니다. Three.js를 사용하면 이러한 유형의 프리미티브를 쉽게 만들 수 있습니다.

// set up the sphere vars
var radius = 50, segments = 16, rings = 16;

// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),

sphereMaterial);

// add the sphere to the scene
scene.add(sphere);

다 좋았으니 구체의 소재는 어떨까요? 코드에서는 sphereMaterial 변수를 사용했지만 아직 정의하지 않았습니다. 먼저, 자료에 대해 좀 더 자세히 설명해야 합니다.

5. 소재

의심의 여지 없이 Three.js의 가장 유용한 부분 중 하나입니다. 메시에 적용할 수 있는 일반적이고 편리한 여러 가지 자료를 제공합니다.

  1. '기본' - '밝지 않은' 상태로 렌더링됨
  2. 램버트

더 있지만 편의상 직접 탐색하도록 하겠습니다. WebGL의 경우 특히 이러한 자료가 생명을 구할 수 있습니다. 왜냐하면 WebGL에서는 렌더링되는 모든 것에 대해 셰이더를 작성해야 하기 때문입니다. 셰이더는 그 자체로 매우 중요한 주제이지만 간단히 말해 GLSL (OpenGL Shader Language)로 작성되어 GPU가 어떻게 보일지 알려줍니다. 즉, 조명, 반사 등의 수학 계산을 모방해야 합니다. 매우 빠르게 복잡해집니다. Three.js를 사용하면 추상화를 원하지 않아도 됩니다. 하지만 셰이더를 작성하려면 MeshShaderMaterial을 사용해도 되므로 유연한 설정이 가능합니다.

하지만 지금은 구에 램버트 머티리얼을 적용해 보겠습니다.

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});

색상 외에 머티리얼을 만들 때 스무딩 지도 또는 환경 지도와 같이 다른 속성을 지정할 수도 있습니다. 머티리얼에 설정할 수 있는 다양한 속성과 엔진이 제공하는 모든 객체를 위키 페이지에서 확인해야 합니다. 최근 새롭게 추가된 threejs.org는 API에 대해 더 매력적인 뷰를 제공합니다.

6. 조명!

지금 장면을 렌더링하면 빨간색 원이 표시됩니다. Lambert 머티리얼을 적용했더라도 장면에 빛이 없으므로 기본적으로 Three.js는 플랫 색상과 동일한 전체 대기광으로 되돌아갑니다. 이 문제를 간단히 해결해 보겠습니다.

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);

7. 렌더링

이제 실제로 렌더링을 위한 모든 설정이 완료되었습니다. 하지만 실제로 바로 그렇게 해야 합니다.

// draw!
renderer.render(scene, camera);

그러나 두 번 이상 렌더링해야 할 수 있으므로 루프를 실행하려면 실제로 requestAnimationFrame을 사용해야 합니다. 이는 브라우저에서 애니메이션을 처리하는 가장 스마트한 방법입니다. 아직 완전히 지원되지 않으므로 폴 아이리시의 shim을 꼭 살펴보시기 바랍니다.

8. 공통 객체 속성

Three.js의 코드를 자세히 살펴보면 Object3D에서 '상속'된 많은 객체를 볼 수 있습니다. 이 객체는 위치, 회전, 배율 정보와 같은 매우 유용한 속성을 포함하는 기본 객체입니다. 특히 구는 Object3D에서 상속되는 메시이며, 여기에 자체 속성(도형소재)을 추가합니다. 이러한 내용을 언급하는 이유는 무엇인가요? 아무 일도 하지 않는 구체만 화면에 두는 것은 바람직하지 않으며, 이러한 속성을 통해 메시와 머티리얼의 기본적인 세부정보를 즉석에서 조작할 수 있으므로 조사할 만한 가치가 있습니다.

// sphere geometry
sphere.geometry

// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array

// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same

9. 더러운 작은 비밀

Three.js에 대해 한 가지 알아두어야 할 점이 있습니다. 예를 들어 메시의 꼭짓점을 수정하면 렌더 루프에서 아무것도 변경되지 않는다는 것입니다. 왜냐하면 Three.js가 메시의 데이터를 최적화의 일환으로 캐시하기 때문입니다. 실제로 해야 할 일은 필요한 것을 다시 계산할 수 있도록 Three.js에 무언가가 변경되었음을 알리는 것입니다. 이를 위해 다음을 실행합니다.

// changes to the vertices
sphere.geometry.__dirtyVertices = true;

// changes to the normals
sphere.geometry.__dirtyNormals = true;

더 많지만 제가 확인한 두 가지가 가장 유용했습니다. 불필요한 계산을 방지하기 위해 변경된 사항만 명확하게 플래그해야 합니다.

결론

이 Three.js에 대한 간단한 소개가 도움이 되었기를 바랍니다. 직접 해보는 것만큼 좋은 법은 없습니다. 이 정도로 강력히 추천하기란 어렵습니다. 브라우저에서 기본적으로 3D로 실행되는 것은 매우 즐거운 일이며 Three.js와 같은 엔진을 사용하면 많은 골칫거리를 덜어주고 정말 멋진 것을 만들 수 있습니다. 이 실습 문서의 소스 코드를 요약했으므로 소스 코드를 참조로 사용할 수 있습니다. 유익하셨다면 Twitter를 통해 알려 주세요. 언제든지 환영합니다.