본문 바로가기
개발/3D Programming

[Three.js] 01) Three.js란 무엇인가? & React에 3D Model 띄우기

by 반비🥰 2024. 5. 28.
반응형
 

[nodejs] obj2gltf 라이브러리로 대용량 obj파일➡️ gltf로 변환하기

오늘은 obj2gltf 라이브러리를 활용해서 대용량 obj파일을 gltf파일로 변환하는 코드를 테스트해 봤다.📌 문제 상황데이터 용량이 적은 obj파일을 gltf로 변환할 때는 문제가 발생하지 않았지만, 용

success-notes.tistory.com


 

 

📌 THREE.js 란?


Three.js는 웹페이지에 3D 객체를 쉽게 렌더링 하도록 도와주는 자바스크립트 라이브러리로 WebGL을 기반으로 작동한다.

WebGL으로 3차원을 구현하려면 많은 양의 코드를 작성해야 한다.

 

WebGL : 점, 선, 삼각형을 그리는 시스템

 

이러한 복잡한 코드를 줄여 3차원을 쉽게 구현할 수 있도록 도와주는 것이 Three.js이다.

 

📌 Three.js 구조


Three.js 라이브러리의 구조를 이해하면 Three.js를 사용하는데 도움이 된다.

Three.js는 크게 Renderer, Scene, Camera로 나눠지며, Scene은 Mesh, Object3D, Group, Light로 구성된다.

또한, Mesh는 Geometry, Materia(+Texture)로 이루어져 있다.

 

Renderer

  • Scene과 Camera를 기반으로 3D 객체를 렌더링 하여 화면에 출력
  • WebGLRenderer를 사용
  • HTML의 Canvas에 3D 객체를 렌더링
impoort { Canvas } from "@react-three/fiber";

const App = ()=>{
	return (
    	<Canvas style={{ width: "100vw", height: "100vh" }}>
        </Canvas>
    );
};

 

Camera

  • Scene을 보는 시점을 정의
  • 원근 카메라(Perspective Camera)와 직교 카메라(Orthographic Camera) 2종류로 나뉨
  • Canvas를 생성하면 기본적으로 원근 카메라가 생성되며, 직교 카메라로 변경할 때는 Canvas 안에 orthographic을 추가해 주면 됨
<Canvas orthographic>
	// ...
</Canvas>

 

Scene

  • 3D 객체를 포함하는 컨테이너로 Mesh, Object3D, Light, Group을 포함
  • 모든 3D 객체를 추가하고 관리하며 렌더링 할 내용을 정의
  • Canvas 컴포넌트 안에 3D 모델 및 조명 정의
<Canvas style={{ width: "100vw", height: "100vh" }}>
   // ...
   <Model />
   <OrbitControls />
</Canvas>

 

[ Scene의 객체 종류 ]

Mesh

  • Geometry와 Material을 결합하여 3D 모델을 생성하는 클래스
  • Geometry와 Material을 통해 객체의 형태와 표면 특성을 정의
  • Material은 Texture를 통해 표면 이미지를 정의
<Canvas style={{ width: "100vw", height: "100vh" }}>
   <Box position={[0, 0, 0]} scale={[1, 1, 1]}>
   	<meshStandardMaterial attach="material" color="skyblue" />
   </Box>
</Canvas>
  • meshStandardMaterial을 통해 색상을 지정

Object3D

  • 모든 3D 객체의 기본 클래스
  • position, rotation, scale 등의 속성으로 3D 공간에서의 위치, 회전, 크기 등을 정의
  • children 배열을 가지고 있어, Object3D 객체를 자식으로 추가 가능
  • add(), remove() 메서드로 자식 객체 추가 및 삭제가 가능
  • lookAt() 메서드로 특정 좌표 보도록 지정 가능

 

Light

  • Scene에 조명을 추가하는 클래스로 3D 객체를 비추고 그림자를 생성하는 데 사용
  • 종류
    • AmbientLight : 모든 방향에서 고르게 비추는 환경 조명
    • DirectionalLight : 특정 방향에서 빛을 비추는 평행 광원
    • PointLight : 특정 지점에서 모든 방향으로 빛을 비추는 광원
    • SpotLight : 원뿔 형태로 특정 방향을 비추는 스포트라이트
<Canvas style={{ width: "100vw", height: "100vh" }}>
   <ambientLight intensity={0.5} /> 
   <pointLight position={[10, 10, 10]} />
   // ...
</Canvas>

 

Group

  • 여러 Object3D 객체를 그룹화하는 클래스
  • 그룹 내의 객체들은 그룹의 변화에 영향을 받음
    • 여러 객체를 하나의 단위로 묶어 변환을 적용 가능
  • object3D의 서브클래스로 동일한 속성과 메서드를 가짐
<Canvas>
   <group>
      <mesh>
         // ...
       </mesh>
   </group>
</Canvas>

 

[ Scene의 객체 내용 정리 ] 

📍 주요 차이점 및 관계
➡️Object3D : 모든 3D 객체의 기본 클래스로, Mesh, Light, Group 모두 Object3D를 상속받아 3D공간에서의 공통 기능을 공유
➡️Mesh : Geometry와 Material을 활용하여 3D 객체 생성
➡️Light : Scene의 조명을 추가해 객체 비춤(+ 그림자 생성)
➡️Group : 여러 객체를 그룹화하여 관리 및 변환 적용 (+ 한 번에 변환 가능)

 

 

👩🏻‍💻React-Three-Fibe를 활용한 3D Model 띄우기


App.js

import "./App.css";
import BoxModel from "./components/BoxModel";

function App() {
    return (
        <div className="App">
            <BoxModel />
        </div>
    );
}

export default App;

 

BoxModel.js

import React from "react";
import { Canvas } from "@react-three/fiber";
import { Box, OrbitControls } from "@react-three/drei";

const ObjModel = () => {
    return (
        <Canvas style={{ width: "100vw", height: "100vh" }}>
            <ambientLight intensity={0.5} />
            <pointLight position={[10, 10, 10]} />
            <Box position={[0, 0, 0]} scale={[1, 1, 1]}>
                <meshStandardMaterial attach="material" color="skyblue" />
            </Box>
            <OrbitControls />
        </Canvas>
    );
};

export default ObjModel;

 

 

 

 

결과 화면

three.js를 활용해서 3D Box 생성 화면

 

📌 Three.js 구현 단계


해당 코드는 React-Three-Fibe를 통해 간략하게 구현한 코드로, Three로만 구현한 코드는 여러 단계를 거쳐 구현되게 된다. Three.js로 구현한 코드는 Canvas 생성 ➡️ Scene 생성 ➡️ Camera 세팅 ➡️ Renderer 세팅 ➡️ Rendering 순으로 5단계에 거쳐 구현된다.

 

Three.js로 구현한 코드

import {PerspectiveCamera, Scene, WebGLRenderer} from "three";

// canvas 지정
const cavnas = document.querySelectorAll('#three-canvas');

// Scene 객체 생성
const scene = new Scene();

// Camera 객체 생성 및 Camera 종류 지정
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// renderer 객체 생성 및 크기 지정
const renderer = new WebGLRenderer({canvas: cavnas});
renderer.setSize(window.innerWidth, window.innerHeight);

// Rendering 세팅
function animate(){
    requestAnimationFrame(animate);
    renderer.render(scene, camera);
    camera.position.z += 0.1;
    camera.position.x += 0.1;
    camera.position.y += 0.1;
}

animate();

 

반응형