사실 three.js는 자유도가 높은만큼 처음에 접근하기 어려운데
react-three/fiber 를 이용하면 굉장히 편하다. react 친화적이기도 하고
대부분의 feature는 찾으면 나오는 것 같기는 한데, 일단 중요 포인트만 잡자면
export default function Example() {
return (
<Canvas>
<Model />
<OrbitControls />
</Canvas>
);
}
위와 같이 도화지 역할을 하는 Canvas
컴포넌트 위에,
3d 물체인 Model
과 OrbitControls
와 같은 옵션을 올려주면 된다.
옵션은 ambientLight
나 pointLight
와 같은 빛이 될 수도 있고
Stars
와 같은 기본으로 제공되는 3d 물체일 수도 있는데
이건 찾아보면 다 나옴
문제는 Model
을 만드는 과정인데,
당연히 물체를 직접 하드코딩으로 만드려고 하면 매우 빡세다.
그래서 다른 3d 작업툴을 이용해서 만든 것을 사용하는 것이 더 나은데
이 때 사용하는 파일형식이 GLTF임
이 파일을 끌어다가 그대로 쓸 수 있으면 굉장히 좋겠지만, 이걸 JSX로 변환하는게
간단한 3d 물체일 때는 크게 상관없지만, 복잡해지면 굉장히 골치아픔
이를 어느정도 도와주는 툴이 있다 (매우 편리함)
바로 Model 파일을 만들어주기 때문에, 사용하기 굉장히 좋은듯
아래의 명령어를 이용하면 됨
npx gltfjsx [model.gltf]
최종코드
import React, { useRef } from "react";
import { useGLTF, OrbitControls } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
function Model({ ...props }) {
const group = useRef();
const { nodes, materials } = useGLTF("/shiba/scene.gltf");
return (
<group ref={group} {...props} dispose={null}>
<group rotation={[-Math.PI / 2, 0, 0]}>
<group rotation={[Math.PI / 2, 0, 0]}>
<group rotation={[-Math.PI / 2, 0, 0]}>
<mesh
geometry={nodes.Group18985_default_0.geometry}
material={nodes.Group18985_default_0.material}
/>
</group>
<group rotation={[-Math.PI / 2, 0, 0]}>
<mesh
geometry={nodes.Box002_default_0.geometry}
material={nodes.Box002_default_0.material}
/>
</group>
<group rotation={[-Math.PI / 2, 0, 0]}>
<mesh
geometry={nodes.Object001_default_0.geometry}
material={nodes.Object001_default_0.material}
/>
</group>
</group>
</group>
</group>
);
}
useGLTF.preload("/shiba/scene.gltf");
export default function ThreeExample() {
return (
<Canvas>
<Model />
<OrbitControls />
</Canvas>
);
}
아래의 링크를 참고했다.
https://onion2k.github.io/r3f-by-example/examples/hooks/rotating-cube/
우리는 box
와 같은 단일 물체가 아닌 group
을 사용하기에
useFrame
안에 group
의 rotation.x(y)
값을 넣어주면 된다.
그런 후 JSX의 가장 상위 group의 props에 rotation-x(y)
를 추가해주면 됨
방법이 다양한 것 같기는 한데, 일단 가장 간단한건 캔버스 카메라 위치조정이다.
<Canvas camera={{ position: [0, 0, 3] }}>
<Model />
<OrbitControls />
</Canvas>
위에처럼 카메라 프로퍼티에 position
을 z축을 0을 주면 가장 가까이 붙는거고
숫자를 높일 수록 카메라 z축이 증가하니, 물체에서 멀어지고, 결국 물체가 작아진다고 보면 된다.