Three.js 기초

송기영개발잘하고싶다·2024년 7월 31일
0

Three.js

목록 보기
1/14

개요

캔버스 다음에 Three.js를 공부를 하고 싶어서 공부를 시작하였다.

Three.js를 공부하기전에 WebGL이라는 용어부터 알고가야하는데 WebGL은 Web Graphic Library의 약자로 웹상에서 2D 및 3D 그래픽을 렌더링하기 위한 로우 레벨 Javascript API 이다. WebGL은 GPU를 사용해서 그림을 그리기 때문에 성능이 좋다고 한다.

로우 레벨 Javascript API이기 때문에 모든부분을 구현해야하는데 이를 간편하게 사용할 수 있도록 도와주는 라이브러리가 Three.js이다.

Three.js뿐만 아니라 Babylon.js, A-frame, p5.js, pixiJS 등과 같은 다양한 라이브러리들이 존재하는데 Three.js가 가장 대중적으로 많이 사용되는 라이브러리이다.

기초

Three.js를 공부하기 위해서는 씬, 카메라, 조명, 매쉬(모양, 재질)의 개념을 알고가야한다.

이를 쉽게 생각하기 위해서는 연극무대를 생각하면서 연극무대는 무대, 카메라, 조명, 배우가 필요하구나를 생각하자!

그리고 전체적으로 Three.js가 그려지는 플로우는 무대위에 카메라, 조명, 배우를 설치하고 마지막에 연출을 한다라는 개념으로 생각하면된다.

카메라(Camera)

Three.js는 3차원이기 때문에 x, y, z축이 존재하는데, 위치를 정할때 x축은 좌우(-, +) y축은 상하(+, -) z축은 앞뒤(+, -)를 의미한다.

Three.js에서는 6가지의 카메라가 존재한다.

이들중에 가장 많이 사용하는 카메라는 PerspectiveCamera(원근 카메라)인데, 우리가 흔히 생각하는 사람이 보는 시야를 생각하면 된다.

리그오브레전드, 디아블로 등과 같이 하늘에서 내려다보는 시야의 카메라는 OrthographicCamera(직교 카메라)를 사용한다.

카메라를 자세하게 설명하면 위 그림처럼 나타낼수있다.

왼쪽에 있는 사진을 보면 PerspectiveCamera는 시야각이 존재한다.

그리고 두 카메라 모두 Near clip plane, Far clip Plane안에 물체가 들어와야 우리가 실제로 물체를 확인할 수 있다.

나머지 카메라들은 위의 링크에서 자세하게 살펴보면 된다.

모양(Geometry)

Three.js는 총 21개의 모양이 존재한다.

재질(Material)

Three.js는 총 18개의 재질이 존재하는데 이들중에는 조명이 없어도 표시가 되는 재질도 존재한다.

조명(Light)

Three.js에는 8개의 조명이 존재한다.

실습

실습에 대한 설치는 생략합니다. 설치방법이 궁금하면 설치방법를 통해 확인하시면 됩니다.

PerspectiveCamera(원근 카메라)

  • index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./main.css" />
  </head>
  <body>
    <canvas id="three-canvas"></canvas>
  </body>
</html>
  • main.js
import * as THREE from "three";

// 정적으로 캔버스 조립
const canvas = document.querySelector("#three-canvas");
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });

// 렌더러 사이즈
renderer.setSize(window.innerWidth, window.innerHeight);

// 씬 생성
const scene = new THREE.Scene();

// 카메라 생성
const camera = new THREE.PerspectiveCamera(
  75, // fov
  window.innerWidth / window.innerHeight, // aspect
  0.1, // near
  1000 // far
);

// 카메라를 기본적으로 설치하면 0, 0, 0 위치에 설치가 되기때문에 물체를 보기위해서는 z축을 이동해주어야함
camera.position.z = 5;
camera.position.y = 1;
camera.position.x = 1;

// 카메라를 씬에 설치해주어야함
scene.add(camera);

// Mesh
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({
  color: "#ff0000",
});

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

// 최종적으로 그려주어야함
renderer.render(scene, camera);

카메라 위치 z축 적용

카메라 위치 z,y,x축 모두 적용

현재 소스코드에는 html파일에 canvas를 선언해서 Three.js에서 사용하고있지만 Three.js라이브러리를 통해 동적으로 생성하는 방법도 있다.

import * as THREE from "three";

// 동적으로 캔버스 조립
// 렌더러 생성
const renderer = new THREE.WebGLRenderer();

// 렌더러 사이즈
renderer.setSize(window.innerWidth, window.innerHeight);

// renderer.domElement는 렌더러가 가지고있는 canvas dom요소임
document.body.appendChild(renderer.domElement);

OrthographicCamera(직교 카메라)

import * as THREE from "three";

// 정적으로 캔버스 조립
const canvas = document.querySelector("#three-canvas");
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });

// 렌더러 사이즈
renderer.setSize(window.innerWidth, window.innerHeight);

// 씬 생성
const scene = new THREE.Scene();

// 카메라 생성
const camera = new THREE.OrthographicCamera(
  -(window.innerWidth / window.innerHeight),
  window.innerWidth / window.innerHeight,
  1,
  -1,
  0.1,
  1000
);

// 카메라를 씬에 설치해주어야함
camera.position.x = 1;
camera.position.y = 2;
camera.position.z = 5;

// 카메라가 0,0,0을 바라보게함
camera.lookAt(0, 0, 0);
// 원근 카메라처럼 z축을 변경하는 느낌을 주려면 zoom을 건들여주어야함
camera.zoom = 0.5;
camera.updateProjectionMatrix();
scene.add(camera);

// Mesh
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({
  color: "#ff0000",
});

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

// 최종적으로 그려주어야함
renderer.render(scene, camera);

줌아웃 전

줌아웃 후

안티앨리어싱

Three.js에서는 안티앨리어싱을 적용이 가능한데 WebGLRenderer의 antialias옵션을 true로 주면 적용이된다.

import * as THREE from "three";

// 정적으로 캔버스 조립
const canvas = document.querySelector("#three-canvas");
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });

적용 전

적용 후

안티앨리어싱을 적용하면 더 부드럽게 표현을 할 수 있다. 하지만 성능 저하가 발생할 수 있다.

조명

이전에 사용한 MeshMeshBasicMaterial의 재질의 경우 조명에 영향을 받지 않기 때문에 MeshStandardMaterial로 변경을 하고 조명을 추가한다.

다양한 조명중에 DirectionalLight으로 실습을 진행했고 이 조명은 태양빛과 유사한 조명이라고 생각하면된다.

다른 것들과 마찬가지로 조명도 위치를 지정해주어야 한다.

  // 조명 추가 (색상, 빛의 강도)
  const light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.z = 5;
  light.position.x = 1;
  scene.add(light);

  // Mesh
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const material = new THREE.MeshStandardMaterial({
    color: "#ff0000",
  });

조명 적용 후

배경색

Three.js에는 두가지 방법으로 배경색을 지정할 수 있는데 renderer에 적용하는 방법과 scene에 적용하는 방법이 있다.

어떤 방법을 사용해도 상관은 없지만 renderer위에 scene이 존재하기 때문에 renderer에 배경색을 지정하고 scene을 지정하게 되면 scene가 우선순위가 있기 때문에 scene에 적용한 배경색으로 처리가 된다.

  // 불투명도 적용 및 배경색 적용
  renderer.setClearAlpha(0.5);
  renderer.setClearColor(0x00ff00);

  // 씬 생성
  const scene = new THREE.Scene();
  scene.background = new THREE.Color("blue");

배경적용

안개

Three.js에서 안개를 추가해주는 방법은 다음과 같은데 우리가 생각하는 안개가아니고 뒤쪽이 뿌옇게 보여지는 처리라고 생각하면 된다.

  const scene = new THREE.Scene();
  scene.fog = new THREE.Fog("black", 3, 7);
  • 적용전

  • 적용후

profile
업무하면서 쌓인 노하우를 정리하는 블로그🚀 풀스택 개발자를 지향하고 있습니다👻

0개의 댓글