Three.js 시작하기

소개

실험 중 일부에 Three.js를 사용해 보았는데 브라우저에서 3D를 시작할 때의 골칫거리를 추상화하는 데 정말 유용했습니다. 이를 통해 카메라, 객체, 조명, 재료 등을 만들 수 있으며 렌더러를 선택할 수 있습니다. 즉, HTML 5의 캔버스, WebGL 또는 SVG를 사용하여 장면을 그릴지 결정할 수 있습니다. 오픈소스이므로 프로젝트에 참여할 수도 있습니다. 하지만 지금은 엔진으로 사용해 보고 배운 내용에 집중하고 몇 가지 기본사항을 설명해 드리겠습니다.

Three.js는 멋진 도구이지만 어려움을 겪을 때가 있을 수 있습니다. 일반적으로 예시, 역엔지니어링, 특정 기능을 찾는 데 상당한 시간을 할애해야 하며 경우에 따라 GitHub를 통해 질문을 해야 합니다. 질문이 있으면 Mr. doobAlteredQualia가 매우 유용합니다.

1. 기본 사항

3D에 대한 기본적인 지식과 JavaScript에 대한 적절한 숙련도가 있다고 가정합니다. 그렇지 않은 경우 이 도구를 사용해 보기 전에 조금 알아두는 것이 좋습니다. 약간 혼란스러울 수 있기 때문입니다.

3D 세상에는 다음과 같은 것들이 있습니다. 만드는 과정을 안내해 드리겠습니다.

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

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

2. 지원

브라우저 지원에 관한 간단한 메모입니다. Google의 Chrome 브라우저는 지원되는 렌더러와 기본 JavaScript 엔진의 속도 측면에서 가장 적합한 브라우저입니다. Chrome은 Canvas, WebGL, SVG를 지원하며 속도가 매우 빠릅니다. Firefox는 버전 4의 등장으로 Chrome에 근접했습니다. JavaScript 엔진은 Chrome의 엔진보다 약간 느린 것 같지만 렌더링 기술에 대한 지원은 우수합니다. Opera와 Safari는 WebGL 지원을 추가하는 중이지만 현재 버전은 캔버스만 지원합니다. Internet Explorer (버전 9 이상)는 캔버스 렌더링만 지원하며 Microsoft에서 WebGL 기능을 추가할 계획이라는 소식은 들어본 적이 없습니다.

3. 장면 설정

모든 렌더링 기술을 지원하는 브라우저를 선택했으며 캔버스 또는 WebGL로 렌더링하려고 한다고 가정합니다. 캔버스와 WebGL이 더 표준적인 선택이기 때문입니다. Canvas는 WebGL보다 더 광범위하게 지원되지만 WebGL은 그래픽 카드의 GPU에서 실행된다는 점에 유의해야 합니다. 즉, CPU는 수행하려는 물리 또는 사용자 상호작용과 같은 렌더링이 아닌 다른 작업에 집중할 수 있습니다.

선택한 렌더러와 관계없이 JavaScript는 성능에 맞게 최적화되어야 합니다. 3D는 브라우저에 가벼운 작업이 아니므로(실제로 가능하다는 것이 놀랍습니다) 코드에서 병목 현상이 발생하는 위치를 신중하게 파악하고 가능하면 제거하세요.

그렇다면 three.js를 다운로드하여 HTML 파일에 포함했다고 가정하고 장면을 설정하려면 어떻게 해야 하나요? 다음 행을 추가하면 됩니다.

// 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. Lambert
  3. Phong

더 많은 기능이 있지만 간단히 설명하기 위해 직접 살펴보시기 바랍니다. 특히 WebGL의 경우 이러한 자료가 큰 도움이 될 수 있습니다. 왜냐하면 WebGL에서는 렌더링되는 모든 항목에 관한 셰이더를 작성해야 하기 때문입니다. 셰이더는 그 자체로 방대한 주제이지만 간단히 말해 GLSL (OpenGL 셰이더 언어)로 작성되며 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에서 '상속'받는 많은 객체를 볼 수 있습니다. 이는 위치, 회전, 크기 정보와 같은 매우 유용한 속성이 포함된 기본 객체입니다. 특히 Sphere는 Object3D에서 상속받은 메시이며 여기에 자체 속성인 geometrymaterials를 추가합니다. 이러한 내용을 언급하는 이유는 무엇인가요? 아무것도 하지 않는 구체를 화면에 표시하고 싶지는 않을 것입니다. 이러한 속성은 메시와 재료의 기본 세부정보를 즉시 조작할 수 있으므로 살펴볼 가치가 있습니다.

// 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. Dirty Little Secrets

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를 통해 알려주세요. 인사드릴 수 있어 항상 기쁩니다.