2 분 소요

1. 3D 웹 개발

High Level: R3F
            Three.js / Babylon.js
Low Level : WebGL / WebGPU

웹에서 3D를 다루기 위해서는 웹 표준 기술인 WebGL 혹은 WebGPU를 사용해야 한다.
하지만 이 기술은 파이프라인, 쉐이더, 수학에 대한 이해가 필요하며, 이를 통해 코드를 작성하는 것은 매우 어렵다.

이 복잡한 기술을 쉽게 사용할 수 있게 해주는 라이브러리가 Three.js이다.

또 Three.js를 리액트에서 사용할 수 있게 하는 라이브러리가 R3F이다.

1.1 Three.js 기본 구조

alt text

  • Renderer: Three.js로 구현된 요소가 렌더링된 결과물 객체
  • Scene: 물체들이 존재하는 장소
  • Mesh: Geometry와 Material로 이루어진 물체
  • Light: 조명
  • Camera: Scene을 어디서 어떻게 바라볼지 결정하는 요소

1.2 개발 환경 세팅

npm i three @react-three/fiber @react-three/drei
npm i -D @types/three

2. Canvas

R3F에서 Canvas 컴포넌트를 렌더하는 것으로 기본적인 Renderer, Scene, Camera를 초기화해준다.

import * as THREE from "three";

// init
const camera = new THREE.PerspectiveCamera(70, width / height, 0.01, 10);
const scene = new THREE.Scene();
const renderer = new THREE.WebGLRenderer({ antialias: true });

// ...

JS에서는 직접 초기화해주었다면, R3F에서는 자동으로 초기화한다.

import { Canvas } from "@react-three/fiber";
import MyElement3D from "./MyElement3D";

export default function App() {
  return (
    <Canvas>
      <MyElement3D />
    </Canvas>
  );
}

Canvas의 자식으로 모델이나 조명, 카메라 설정 등을 추가한다.

3. Scene

3.1 좌표계

alt text

// axesHelper를 통해 좌표계를 확인할 수 있다.
<axesHelper scale={10} />

3.2 회전 방향

  • (+) 회전 방향은 반시계 방향이다.
  • 라디안 단위를 사용한다.: (도 단위) * (PI / 180)
    <mesh rotation-x={45 * (Math.PI / 180)} />
    <mesh rotation-x={THREE.MathUtils.degToRad(45)}>
    

4. mesh

mesh: 렌더링되는 3차원 모델

mesh = Geometry + Material 뼈다귀(geometry)와 material(껍데기)를 합한 것이 mesh(Object)이다.

<mesh>
  <boxGeometry />
  <meshStandardMaterial color="#eeff00" />
</mesh>

4.1 Geometry

Geometry: mesh의 모양을 정의

Three.js에서 제공하는 기본 Geometry 클래스 alt text

Geometry에 따른 mesh 생성 방법 3가지

  1. Three.js Element 사용

    <mesh>
      <boxGeometry />
      <meshStandardMaterial />
    </mesh>
    
  2. react-three@drei 사용

    import { Box } from "@react-three/drei";
    
    <Box>
      <meshStandardMaterial />
    </Box>;
    
  3. mesh의 geometry attribute 이용

    const geometry = new THREE.BoxGeometry()
    
    <mesh geometry={geometry}>
      <boxGeometry />
    </mesh>
    


기본 Geometry를 생성할 때 옵션 지정하기

R3F에서는 args 어트리뷰트로 생성되는 Geometry를 제어할 수 있다.
이 args는 Three.js에서 Geometry 클래스의 생성자 인자값에 해당한다.

각 args에 대한 정보는 Three.js 문서에서 확인할 수 있다.

boxGeometry의 예시

new THREE.BoxGeometry(1, 1, 1, 2, 2, 2);
<boxGeometry args={[1, 1, 1, 2, 2, 2]} />
  • width: x축 기준 length
  • height: y축 기준 length
  • depth: z축 기준 length
  • widthSegments: 가로 방향으로 분할할 사각형 면의 수
  • heightSegments: 세로 방향으로 분할할 사각형 면의 수
  • depthSegments: 깊이 방향으로 분할할 사각형 면의 수

4.2 Material

Material: mesh의 재질

<mesh>
  <boxGeometry />
  <meshStandardMaterial color="#ffffff" />
</mesh>

5. Light

5.1 광원의 종류

  • AmbientLight: 자연광
  • HemisphereLight: 반구광
  • DirectionalLight: 직사광(태양)
  • PointLight: 한 점에서 뻗어나가는 광원
  • SpotLight: 조명광(원뿔)
  • RectAreaLight: 사각형태의 조명(형광등)
  • Environment: Drei에서 제공하는 Light

5.2 그림자

그림자를 지원하는 광원: DirectionalLight, PointLight, SpotLight
Drei에서 제공하는 그림자 컴포넌트: AccmulativeShadows, ContactShadows, SoftShadows

광원을 통한 그림자 만들기

export default function App() {
  return (
    <Canvas shadows>
      <directionalLight castShadow />

      <mesh receiveShadow>
        <boxGeometry />
        <meshStandardMaterial color="#ffffff" />
      </mesh>
    </Canvas>
  );
}
  • Canvas의 shadows: 그림자 시스템이 전체 Canvas에서 작동하도록 설정
  • 조명의 castShadow: 조명이 물체에 대해 그림자를 생성하도록 설정
  • mesh의 castShadow: 해당 mesh가 다른 객체 위에 드림자를 드리우도록 설정
  • mesh의 receiveShadow: 해당 mesh가 다른 객체의 그림자를 받을 수 있도록 설정

6. Camera

Three.js에서 두 가지 카메라의 종류
alt text

카메라의 종류에 따라 시야 범위를 정의하는 6개의 평면으로 이루어진 절두체가 다르다.
절두체에 들어간 물체만이 화면에 렌더링된다.

alt text


<Canvas />를 선언했을 때 기본적으로 Perspective Camera를 생성한다.
또 파라미터 중 Aspect는 웹에서 canvas에 해당하는 영역의 비율로 자동 설정된다.
따라서 카메라를 조정할 때는 나머지 3가지 파라미터만 신경 쓰면 된다.

export default function App() {
  return (
    <Canvas camera=>
      <MyElement3D />
    </Canvas>
  );
}

카테고리:

업데이트:

댓글남기기