웹개발

[Next.js] React-Three-fiber 을 사용하여 3D 모델 프로젝트에 추가 및 애니메이션 적용하기

Heeyeon Choi 2024. 12. 6. 17:32
728x90

1. 3D 모델 구하기 (gltf)

우선 3D 모델을 구하기 위해서 저는 

https://lumalabs.ai/genie?view=preview

 

Luma AI - Genie

A 3d generative foundation model

lumalabs.ai

를 사용했습니다! 

 

1-1. 원하는 모델을 입력하기

1-2. 원하는 모델을 선택하여 다운로드하기 

 

다운로드할때, gltf 형식으로 합니다. 웹에 제일 적절한 포맷입니다. 

 

GLTF와 기타 포맷 비교

포맷 크기 성능 최적화 호환성  주요 특징
GLTF 작음 매우 높음 웹 표준 지원 경량, 스트리밍 지원, PBR 렌더링 지원
OBJ 낮음 제한적 오래된 포맷, 텍스처 포함 불가
FBX 중간 제한적 애니메이션 지원, 폐쇄적 포맷
COLLADA 중간 제한적 XML 기반, 파일 크기 크고 느림

 

 

2. Next.js(React.js) 프로젝트에 추가 및 애니메이션 적용하기

2-1. React Three Fiber install 하기

npm install @react-three/fiber @react-three/drei three

 

2-2.GLTF 파일 렌더링하기

'use client';
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { OrbitControls, useGLTF } from '@react-three/drei';

const Model = () => {
  const gltf = useGLTF('/models/example.gltf'); // GLTF 파일 경로
  return <primitive object={gltf.scene} />;
};

const GltfViewer: React.FC = () => {
  return (
    <div className="w-full h-[500px]">
      <Canvas>
        <ambientLight />
        <directionalLight position={[1, 1, 1]} />
        <Model />
        <OrbitControls />
      </Canvas>
    </div>
  );
};

export default GltfViewer;

 

2-3. gltf 파일 불러오기

 

  • GLTF 파일을 public/models/example.gltf에 저장.
  • useGLTF('/models/example.gltf')를 통해 로드.

2-4. 애니메이션 적용하기 (회전과 Pulse 애니메이션)

'use client';
import React, { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, useGLTF } from '@react-three/drei';

const AnimatedModel = () => {
  const gltf = useGLTF('/models/star.glb'); // GLTF 파일 경로
  const ref = useRef<THREE.Group>(null); // GLTF 모델의 참조

  // 애니메이션 추가
  useFrame(({ clock }) => {
    if (ref.current) {
      const time = clock.getElapsedTime(); // 경과 시간 가져오기

      // 회전 애니메이션
      ref.current.rotation.y = time; // Y축 회전 (1초에 한 바퀴)

      // Pulse 애니메이션
      const scale = 1 + Math.sin(time * 2) * 0.1; // 크기를 부드럽게 변화
      ref.current.scale.set(scale, scale, scale); // X, Y, Z 축의 크기 조정
    }
  });

  return <primitive ref={ref} object={gltf.scene} />;
};

const GltfViewer: React.FC = () => {
  return (
    <div className="w-full h-[500px]">
      <Canvas>
        <ambientLight intensity={0.5} />
        <directionalLight position={[1, 1, 1]} />
        <AnimatedModel />
        <OrbitControls />
      </Canvas>
    </div>
  );
};

export default GltfViewer;

useFrame 을 활용하여 다양한 애니메이션을 추가할 수 있습니다.

3.결과

 

 

 

728x90