[Three.js] 포트폴리오를 위한 개발?! - 1편

Ted·2023년 8월 9일
0

포폴

목록 보기
1/2
post-thumbnail

나를 소개하는 포트폴리오로 3D를 사용해보면 어떨까해서 찾아보던 중 알게된 Three.js를 활용한 개발!!

Vanila Javascript

Vanila를 활용한 개발을 하려고 한다!
먼저 만들고 싶은 파일 안에 프로젝트를 생성한다.

$ npm create vite ios-threejs --template vanila

그리고 다음과 같이 three.js를 설치한 후에 서버를 열어본다.

$ npm i three
$ npm run dev

그럼 자동적으로 localhost:5173에 해당하는 브라우저가 열릴 것이다.

다음 main.js를 열어서 다음과 같이 코드를 작성해보자.

import * as THREE from "three";

const renderer = new THREE.WebGLRenderer();

const app = document.querySelector("#app");
app.appendChild(renderer.domElement);
renderer.setSize(window.innerWidth, window.innerHeight);

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.01,
  1000
);
camera.position.z = 5;
camera.position.y = 2;
scene.add(camera);

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: "red" });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

renderer.render(scene, camera);

다음은 style.css파일을 수정해서 해당 만든 mesh가 보이게 한다.

#app {
	position: absolute;
	top: 0;
	left: 0;
}

코드 설명을 잠시 하자면 geometry를 통해 원하는 도형을 구성하고 도형의 재질을 material로 구성하고 이를 mesh로 함축시킨다.

// 간단하게 박스 모양의 geometry를 추가하고, 너비, 높이, 깊이를 각각 1,1,1로 설정한다.
const geometry = new THREE.BoxGeometry(1, 1, 1);

// 빛의 영향을 받지 않는 MeshBasicMaterial을 추가하고, 색은 개인적으로 좋아하는 초록색으로 했다.
const material = new THREE.MeshBasicMaterial({ color: 'red' });

// mesh에 앞서 만든 geometry와 material을 인자로 넣어서 만든다.
const mesh = new THREE.Mesh(geometry, material);

// scene에 방금 만든 mesh를 추가한다.
scene.add(mesh);

renderer.render(scene, camera);

카메라의 경우 우리가 보는 화면을 뜻하고 이게 없으면 답이 없다...

const camera = new THREE.PerspectiveCamera(
  75, // fov(시야각) 값이다.
  window.innerWidth / window.innerHeight, // aspect ratio 값으로서, 카메라의 가로세로 비율 이다.
  0.1, // near 값이다.(이 거리보다 가까운 객체는 카메라에 담기지 않는다.)
  100 // far 값이다.(이 거리보다 먼 객체는 카메라에 담기지 않는다.
);

이렇게 하면 개뜬금 빨간색 박스가 이렇게 있는 것을 볼 수 있다.


사진은 x축과 y축을 기존 코드에서 좀 바꿔서 이렇게 되었다..!

그리고 다음은 카메라의 앵글을 직접 수정해서 바꾸는 방식이 아니라 좀 편하게 다루기 위한 방법이다.

일단 다음 코드를 제거한다. 이제는 render를 다른 방식으로 보여줄 것이다. 사실 제거가 아니라 함수에 넣을 것이다!

renderer.render(scene, camera);

다음과 같이 코드를 수정해본다!

const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.enableDamping = true;
// 딱딱 끊기는 현상 제거
orbitControls.dampingFactor = 0.05;
// 값이 작을 수록 드래그가 멈췄을 때 살짝 움직이는 느낌 생기게함

const handleRender = () => {
  orbitControls.update();
  renderer.render(scene, camera);
  renderer.setAnimationLoop(handleRender);
};

const handleResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.render(scene, camera);
};

window.addEventListener("resize", handleResize);
handleRender();

OrbitControls를 사용하기 위해서 위에 다음의 코드도 추가해야한다.

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

OrbitControls를 통해서 우리는 카메라의 궤도를 마우스로 움직이게 할 수 있다.

handleRender() 함수를 살펴보면 아까 없앴던 renderer.render의 코드가 있다. 따라서 setAnimationLoop 함수를 통해 계속 바뀐 앵글에 대한 장면을 render해주는 것이다.

아래 handleResize() 의 경우 resize가 될 때 callback을 위한 함수이다. 동일하게 renderer.render를 통해 계속 업데이트 시켜준다.

이제 실행시켜보면 마우스 왼쪽으로는 각도가 오른쪽으로는 도형의 위치이동이 가능해진다!

그리고 추가적인 코드로
handleRender() 함수에 다음과 같은 코드를 추가하면 회전하거나 올라가는 식의 애니메이션을 만들 수 있다. 각 축에 더하거나 빼보면서 살펴보면 좋을 것같다.

mesh.position.y += 0.001;
mesh.rotation.y += 0.01;

또한 끝부분이 너무 뾰족해보이면 안티엘리어싱을 추가해서 뭉툭하게 할 수 있다.

const renderer = new THREE.WebGLRenderer({
    antialias: true,
  });

참고 블로그
앗-Threejs를 복습해보자-1탄, 2탄
Three.js-journey 강의노트

profile
iOS Developer

0개의 댓글