Creating a scene - Yena-Yun/tiny-three-js Wiki

  • three.js로 뭔가를 보여주려면 scene, camera, renderer가 필요하다.
  • camera를 가지고 scene을 render하게 된다.

scene 셋팅

const scene = new THREE.Scene();

camera 셋팅

PerspectiveCamera

const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

  • three.js엔 여러 camera가 있다.
  • 그 중에 PerspectiveCamera를 알아보자.

1. field of view (FOV)

   특정 순간에 화면에 scene이 보여지는 범위, 값은 degree 단위

2. aspect ratio

   요소의 너비를 높이로 나눈 값을 주로 사용
   (안 그러면 와이드스크린 TV에서 오래된 영화를 재생할 때처럼 이미지가 찌그러져 보임)

3. near, far 클리핑 평면

   camera에서 far 값보다 멀리 떨어져 있거나 near 값보다 가까운 물체는 render 되지 않음 
   (지금 신경쓸 부분은 아님)

renderer 셋팅

1. WebGLRenderer

const renderer = new THREE.WebGLRenderer();

  • renderer는 주로 WebGLRenderer 객체를 사용한다.

2. setSize

renderer.setSize(window.innerWidth, window.innerHeight);

  • setSize를 통해 renderer가 앱에서 렌더링되는 사이즈를 설정해준다.

    - 주로 앱을 꽉 채우는 width와 height를 사용한다. (= window.innerWidth, window.innerHeight)
    
  • 성능이 중요한 앱이라면 setSize에 더 작은 값을 주기도 한다.

  • 예: window.innerWidth/2 또는 window.innerHeight/2 (=> 앱을 4분의 1 사이즈로 렌더링)

  • 앱의 사이즈는 그대로 유지하면서 더 낮은 해상도로 render를 하고 싶다면?

    • setSize의 3번째 항(updateStyle)에 false를 준다.
    • 예: setSize(window.innerWidth/2, window.innerHeight/2, false)
    • => 앱을 절반의 해상도로 렌더링 (단, <canvas>의 width와 height가 100%인 경우)

3. DOM에 추가하기

document.body.appendChild(renderer.domElement);

  • 만들어진 renderer를 DOM 요소로 <canvas>에 추가한다.
    • <canvas>: renderer가 scene을 보여주기 위해 사용하는 element(태그)

렌더링할 cube 만들기

1. BoxGeometry

const geometry = new THREE.BoxGeometry(1, 1, 1);

   - cube를 만들기 위해 BoxGeometry 객체를 사용
   - BoxGeometry: cube의 모든 모서리(vertices)와 면(faces)을 담고 있는 객체

2. MeshBasicMaterial

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

  - 여러 material 중 MeshBasicMaterial을 사용
  - 모든 material들은 여러 속성(예: color)을 가지고 있다.

3. Mesh

const cube = new THREE.Mesh(geometry, material);

  만든 geometry와 material을 적용하여 하나의 cube를 생성

4. scene.add()

scene.add(cube);

  만든 cube를 scene에 추가

5. camera 관련 유의점

camera.position.z = 5;

  • scene.add()를 호출하면 기본적으로 (0,0,0) 좌표에 추가되는데, 이러면 camera와 cube가 둘 다 내부(inside)에 있게 된다.
  • 이를 방지하기 위해 camera를 약간 바깥쪽으로 이동시키는 위와 같은 코드도 작성한다.

Scene 렌더링하기

  • 아직까지는 화면에 아무 것도 안 보일 것이다.

  • 기본적으로 뭔가를 움직이거나 변화를 일으키고 싶다면 animate loop를 통과해야 한다.

    (이 `animate loop`가 너무 길어지지 않도록 하기 위해 loop 내에 함수를 호출하여 사용하기도 함)
    

Animate loop

function animate() { requestAnimationFrame( animate ); renderer.render( scene, camera ); } animate(); `

  • animate loop를 통과하면,
  • 화면이 새로고침 될 때마다(= 1프레임, 1초 당 60번) renderer가 scene을 다시 그리게 된다.

requestAnimationFrame

  • setInterval를 쓸 수도 있지만 requestAnimationFrame의 장점이 더 크다.

     - 이 장점 중에 유저가 다른 브라우저 탭을 탐색할 때 잠깐 '멈춘다'는 점이 가장 중요!
     - (=> 처리 속도를 더 높이고 자원 낭비를 줄인다)
    

cube 움직이게 하기

  • 위의 코드들을 잘 추가했다면 화면에 녹색 박스가 보일 것이다.

  • animate 함수의 renderer.render 라인 위에 다음 코드들을 추가하자.

cube.rotation.x += 0.01; cube.rotation.y += 0.01;

  • 이렇게 하면 매 프레임(1초 당 60번)마다 cube가 회전하게 된다.
⚠️ **GitHub.com Fallback** ⚠️