본문 바로가기

공부일지/Three.js

Three.js 공부하기 3D 큐브 만들기

728x90
반응형

안녕하세요. 에디터M입니다.

저번시간에 만든 2D 큐브를 3D큐브로 변경하는 작업을 이어 포스팅 해보려고 해요.

이전 포스팅을 못 보신 분들은 참고 부탁드려요.

 

Three.js 공부 하기 : Three.js 알아보기

안녕하세요. 에디터M입니다. 오늘은 어제에 이어서 Three.js 공부하기 Three.js 알아보기 포스팅을 해볼께요. 먼저 Three.js가 무엇인지 알아볼까요? Three.js 란? Three.js는 웹 기반 3D 그래픽을 생성하고

min-webstory.tistory.com

 

 

Three.js 공부 하기 : Three.js 심화 학습

안녕하세요. 에디터M입니다. 오늘은 어제에 이어서 Three.js 공부하기 3D 큐브 만들기 해볼게요. 혹시 이전 내용을 못 보신 분들은 이전 내용을 보고 오시는 걸 추천드려요. 2023.07.12 - [공부일지/Front

min-webstory.tistory.com

 

저번 시간에 초록색 2D 큐브가 출력되는 부분까지 작업했었죠?

 

2D 큐브에서 3D 큐브로 만들기


우리가 저번에 만들었던 2D큐브도 처음에 정육면체라고 해서 만들었지만 화면에 출력된 큐브는 2D로 되어 있었죠?

카메라가 -Z 방향을보고 있고, 정육면체도 Z 축에 맞춰서 정렬이 되어 있어서 2D처럼 보이는 거에요.

 

3D처럼 보기 위해선 애니메이션을 구현하는 requestAnimationFrame을 호출해야되요.

function render(time) {
  time *= 0.001;  // convert time to seconds
 
  cube.rotation.x = time;
  cube.rotation.y = time;
 
  renderer.render(scene, camera);
 
  requestAnimationFrame(render);
}
requestAnimationFrame(render);

requestAnimationFrame은 브라우저에서 애니메이션 프레임을 요청하는 함수인데요. 

우리가 이전 포스팅에서 작업했던 renderer을 render안에 넣어줍니다.

 

requestAnimationFrame안에 render을 넣었는데 이 경우에는 우리가 그냥 평소에 쓰던방식대로 render() 이런식으로 render함수를 실행하면 한번밖에 실행 되지 않기 때문에 애니메이션 프레임 안에 넣으면 변화가 있으면 실행 되게 합니다.

 

requestAnimationFrame은 매개변수로 넘겨받은 함수에 페이지가 로드된 이후의 시간값을 밀리초 단위로 넘겨줍니다.

전 초 단위가 더 익숙하기 때문에, 밀리초 단위를 초 단위로 변경하였습니다.

 

그리고 큐브의 x,y의 회전값을 시간 단위로 설정했습니다. 회전값은 라디안 단위로 사용하는데 라디안은 우리말로 호도 라고 하는데 원의 각도라고 생각하면 쉽습니다. 360도는 2π(3.14 * 2) 6.18초 마다 한 바퀴씩 회전합니다.

 

render안에 requestAnimationFrame를 다시 선언해하는 재귀함수를 사용해서 무한 반복하게 합니다.

그럼 계속 시간을 받고 그 만큼 회전하게 됩니다.

 

3D큐브
3D큐브 이미지

실제 출력 화면에선 회전하는 큐브가 나오게 됩니다.

import * as THREE from 'three';

function main() {
  const canvas = document.querySelector('#cube');
  const renderer = new THREE.WebGLRenderer({antialias: true, canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();

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

  const material = new THREE.MeshBasicMaterial({color: 0x44aa88});  // greenish blue

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

  function render(time) {
    time *= 0.001;  // convert time to seconds

    cube.rotation.x = time;
    cube.rotation.y = time;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

}

main();

실제 js코드는 이렇게 됩니다.

 

그리고 이제 회전은 하는데 입체갑은 없어 보이는데 이제 그림자와 선을 넣어볼께요.

나중에 조금 더 자세히 다룰 DirectionalLight를 사용해서 작업 해볼게요.

DirectionalLight 알아보기


DirectionalLight에는 위치(position), 목표(target),의 속성이 있습니다.

const color = 0xFFFFFF;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light);

빛의 색상을 정하고, 빛의 강도를 정의해서 전달 해 줍니다.

그리고 positon은 북서쪽방향으로 하고 Z축은 약간 위로 보내며 target은 따로 설정 하지 않아 (0,0,0)이 됩니다.

 

그리고 큐브의 material도 변경해줘야 합니다.

MeshBasicmaterial은 광원에 반응 하지 않기 때문에 meshPhongMaterial로 변경 해줍니다.

 

이제 총 완성 코드입니다.

// Three.js - Fundamentals with light
// from https://threejs.org/manual/examples/fundamentals-with-light.html


import * as THREE from 'three';

function main() {
  const canvas = document.querySelector('#c');
  const renderer = new THREE.WebGLRenderer({antialias: true, canvas});

  const fov = 75;
  const aspect = 2;  // the canvas default
  const near = 0.1;
  const far = 5;
  const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.z = 2;

  const scene = new THREE.Scene();


  const color = 0xFFFFFF;
  const intensity = 1;
  const light = new THREE.DirectionalLight(color, intensity);
  light.position.set(-1, 2, 4);
  scene.add(light);
 

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

  const material = new THREE.MeshPhongMaterial({color: 0x44aa88});  // greenish blue

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

  function render(time) {
    time *= 0.001;  // convert time to seconds

    cube.rotation.x = time;
    cube.rotation.y = time;

    renderer.render(scene, camera);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

}

main();

다음시간에는 좀더 심화 공부를 포스팅 해볼게요.

그럼 다음시간에 봐요~~

728x90
반응형