three-fiber이란?
3D 모델링 파일 구하기
무료로 배포된 모델파일 사용 ( 나는 sketchfab 을 이용했다 )
자동차의 경우 흔한 모델이라 쉽게 구할 수 있었다.
gltf 모델링 파일을 jsx 컴포넌트로 바꾸기
npx gltfjsx 모델링파일.gltf
gltf loader
가 아무리해도 경로 설정이 되질 않아서 다른 방법을 찾아보니 이런식으로 컴포넌트 화 시켜주는 라이브러리가 있었다.
ThreeModel
import { useRef, Suspense } from "react";
import { extend, useFrame } from "@react-three/fiber";
import { OrbitControls, useGLTF } from "@react-three/drei";
function Model(props) {
const { nodes, materials } = useGLTF("/scene.gltf");
return (
<group {...props} dispose={null}>
<group rotation={[-Math.PI / 2 - 0.01, 0, -Math.PI]}>
<mesh
geometry={nodes.Object_2.geometry}
material={materials["Material.001"]}
/>
...
</group>
</group>
);
}
useGLTF.preload("/scene.gltf"); // 생성된 컴포넌트의 코드를 복붙해서 붙여놓은것
export default function ThreeModel() {
return (
<>
<object3D ref={object3d}>
<OrbitControls/> // 카메라 컨트롤
<Suspense fallback={null}>
<Model />
</Suspense>
</object3D>
</>
);
}
fiber
를 사용해 렌더링 시켜주면 기초 작업은 끝/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { Canvas, useFrame } from "@react-three/fiber";
import ThreeModel from "./ThreeModel";
const container = css`
height: 71.5vh;
width: 100%;
overflow: hidden;
background-color: black;
display: flex;
justify-content: center;
z-index: 10;
position: relative;
`;
const color = 0xffffff;
const intensity = 1;
export default function CarModel() {
return (
<div css={container}>
<div
css={{
width: "80%",
height: "100%",
}}>
<Canvas
camera={{
fov: 5,
near: 10,
aspect: window.innerWidth / window.innerHeight,
far: 1000,
position: [-45, 10, 50],
}}>
<pointLight color={color} intensity={intensity} /> //
<directionalLight color={color} intensity={intensity} /> // 조명에 대한 옵션들
<ambientLight color={color} intensity={intensity} /> //
<ThreeModel /> // 이게 gltfjsx를 이용해 컴포넌트화 시킨 컴포넌트
</Canvas>
</div>
</div>
);
}
이렇게하면 기본적으로 마우스 클릭과 휠에 따라 움직이는 모델링이 렌더링된다.
3D 텍스트 더하기 (Textgeometry)
홈 화면에 차 하나만 덜렁 있기에 너무 허전해서 서비스 명을 3D 모델링 시키고자 한다.
TextGeometry
사용, 폰트 자체를 렌더링 시키는 과정은 굉장히 간단하다.
필요한 라이브러리 및 폰트 임포트
import { FontLoader } from "three/examples/jsm/loaders/FontLoader";
import { TextGeometry } from "three/examples/jsm/geometries/TextGeometry";
import ThreeFont from "../../assets/3dFont/Oswald_Bold.json";
사용할 폰트를 FontLoader
을 이용해 font 객체를 생성한다.
const font = new FontLoader().parse(ThreeFont);
모델링 컴포넌트 내에 textGeomtry를 이용해 args를 필요한 prop해주준다.
<mesh>
<textGeometry args={["CAR-BORN", { font, size: 1.1, height: 1 }]} /> // args=[["텍스트",{옵션}]]
<meshLambertMaterial attach="material" color={"red"} />
</mesh>
손쉽게 3D모델링 브라우저에 렌더링하기 끝! 하지만 무엇인가 아쉽다...
three-fiber 자동으로 회전 시키기
OrbitControls
의 옵션 중 autoRotate 사용 return (
<>
<object3D ref={object3d}>
<OrbitControls autoRotate/>
<Suspense fallback={null}>
<Model />
</Suspense>
</object3D>
</>
);
}
export default function ThreeModel() {
const object3d = useRef(null);
const controlsRef = useRef(null);
useFrame(() => {
controlsRef.current.update();
if (controlsRef.current.getAzimuthalAngle() < -0.97) {
controlsRef.current.autoRotateSpeed = -0.2;
} else if (controlsRef.current.getAzimuthalAngle() > -0.6) {
controlsRef.current.autoRotateSpeed = 0.2;
}
});
return (
<>
<object3D ref={object3d}>
<OrbitControls
...
완성도 높이기
<OrbitControls
ref={controlsRef}
minAzimuthAngle={-Math.PI / 3}
maxAzimuthAngle={0.06}
minPolarAngle={Math.PI / 2.2}
maxPolarAngle={Math.PI - Math.PI / 2}
enableZoom={false}
autoRotate
/>
사용자 완성 홈화면