리액트에서 Three.JS 사용하기

김찬진·2023년 2월 21일
2

Three

목록 보기
1/8

웹에서 3D 모델 및 인터렉티브한 웹을 다루기 위해선 Three.JS 라이브러리를 다룰줄 알아야합니다. Three.js 자체는 글도 많고 여러가지 강의가 있지만, React 기반의 React-three-fiber 혹은 React-three-drei에 대해서는 설명이 부족하고 외국에서도 설명이 많이 없더군요.

React기반으로 Three.js를 다루기위해 먼저 Three.js가 뭔지 알아보겠습니다.

Three.js 란?

three.js는 webGL을 이용하여 3D 그래픽을 구현하기 위한 자바스크립트 라이브러리입니다. 개발자들이 인터렉티브하고 다이나믹한 3D 컨텐츠를 쉽게 개발할 수 있도록 도와줍니다.

쉽게 말하면 어디선가본 존나 멋있는 사이트들은 대부분 Three.js로 만들어졌다고 생각하시면됩니다.

Three.js를 구현하기 위한 준비

//scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);

//camera setting
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.set(0, 0, 3);

//renderer
const renderer = new THREE.WebGLRenderer({
  //안티엘리어싱
  antialias: true,
  //아무것도 없는 공간은 투명하게
  alpha: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

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

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

// 반응형 처리
function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener("resize", onWindowResize);

가장 기초적인 코드입니다. 먼저 맨 윗줄부터 보도록 하겠습니다.

Scene

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);

Scene 함수입니다. 현실로 비유하면 공간이있어야 무엇이든 볼 수 있습니다. 쉽게 이 Scene은 공간이라고 생각하면 됩니다.

Camera

//camera setting
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.set(0, 0, 3);

사람은 무언가를 본다하는건 으로 무언가를 본다라고 할 수 있습니다. 컴퓨터는 눈이 없으므로 무언가를 보기위해선 카메라가 필요합니다. 사람은 눈이 2개 밖에없지만 카메라는 눈알을 몇개라도 생성할 수 있고, 심지어 눈알의 종류 도 바꿀 수 있습니다. 이 눈알의 종류에는 어떤 것들이 있는지 봐보겠습니다.

  • PerspectiveCamera : 원근법이 적용된 카메라입니다. 일반적인 눈알입니다.
  • OrthographicCamera : 원근법이 적용되지 않는 카메라입니다. 일반적으로 2D 장면을 표현할때 사용합니다.
  • CubeCamera : 육면체 모양의 카메라로 Scene 안에서 또다른 공간을 만들 때 사용합니다.

현재함수에는 원근법이 적용된 PerspectiveCamera 카메라를 사용하였는데 이 카메라에 적용된 4개의 메소드들이 각각 무엇을 뜻하는지 알아보겠습니다.

일반적으로 ThreeJS에서 PerspectiveCamera( fov, aspect, near, far ) 이런 메소드로 정의됩니다.

  • fov : 시야각(Field of View)입니다. 수직 방향으로 보이는 시야각을 지정합니다.

  • aspect : 카메라가 보여줄 가로/세로 비율입니다. 보통 브라우저 창을 기준으로 정하기 때문에 window.innerWidth / window.innerHeight 를 사용합니다.

  • near : 카메라에서부터 얼마나 가까이 있는 것까지 렌더링할지 지정합니다. 이 값보다 가까이 있는 것은 렌더링되지 않습니다.

  • far : 카메라에서부터 얼마나 멀리 있는 것까지 렌더링할지 지정합니다. 이 값보다 멀리 있는 것은 렌더링되지 않습니다.

카메라의 속성을 지정해 주었으니 이제 카메라의 위치를 지정해주어야합니다. 위 코드에서는

camera.position.set(0, 0, 3);

으로 지정해주었습니다. 이는 x좌표는 0, y좌표 0, z좌표는 3 인 위치에 지정한다는 의미입니다.

position은 위치정보이기때문에 음수,소수로도 입력이 가능합니다.

camera.position.set(-1.3, 5.5, -10);

renderer

//renderer
const renderer = new THREE.WebGLRenderer({
  //안티엘리어싱
  antialias: true,
  //아무것도 없는 공간은 투명하게
  alpha: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

공간과 카메라가 있지만 컴퓨터는 멍청해서 웹에서 렌더링을 해줘야합니다. 렌더링을 진행해주는 함수를 renderer라고 부릅니다. 다행히 React-three-fiber에는 이 renderersceneCanvas 라는 컴포넌트에서 지원해 줍니다. React-three-fiber를 사용하실 분은 이런게 있다라고만 알면 되겠습니다.

mesh

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

공간과 카메라와 눈과 렌더러까지 있지만 아직까진 아무것도 보이지않습니다. 뭘 보여주려고하는지 아직 정해주지않았기때문입니다. 3D 객체의 기본 요소인 mesh를 정의해줘야합니다. mesh도 geometrymaterial로 나뉘는데 각각 지오메트리는 객체의 모양과, 구조 머터리얼은 객체의 색상 등을 정의해줍니다.

위 코드에서는 크기가 1인 cyan색상 box모양을 정의하였고, 이를 cube라는 이름을 가진 mesh에 담고 scene에 추가하였습니다.

animation

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

마지막으로 위 코드는 Scene, camera, rendere, mesh를 이용하여 애니메이션을 구현하는 코드입니다. requestAnimationFrame 함수를 이용하여 브라우저에게 다음 프레임을 그리도록 요청하고 프레임마다 cube.rotation.y += 0.01; 큐브의 y축 회전값을 0.01만큼 증가시키라고 요청합니다. 최종적으로 큐브가 y축으로 회전하는 모습이 완성됩니다.

React-three-fiber에서는 useFrame()함수를 사용하여 각 프레임을 호출할 수 있습니다.

Light

const AL = new THREE.AmbientLight(0xffffff, 1);
scene.add(AL);

장면과 카메라와 렌더러와 매쉬까지 지정되었지만 여전히 우리는 아무것도 볼 수 없습니다. 현실에서도 무언가를 본다는 것은 이 무언가에 반사되어 보는 것입니다. 그렇기때문에 빛을 Scene에 추가해 줘야합니다. 여기에서는 광역적으로 빛을 반사해주는 AmbientLight를 사용하였습니다. 빛의 종류에 대해선 추후 React-three-fiber에서 React component 형식으로 정리하겠습니다.

profile
AI/Web 개발자

0개의 댓글