three.js

이동창·2021년 11월 10일
0

react-three/fiber

사실 three.js는 자유도가 높은만큼 처음에 접근하기 어려운데
react-three/fiber 를 이용하면 굉장히 편하다. react 친화적이기도 하고

대부분의 feature는 찾으면 나오는 것 같기는 한데, 일단 중요 포인트만 잡자면

export default function Example() {
    return (
        <Canvas>
            <Model />
            <OrbitControls />
        </Canvas>
    );
}

위와 같이 도화지 역할을 하는 Canvas 컴포넌트 위에,
3d 물체인 ModelOrbitControls와 같은 옵션을 올려주면 된다.

옵션은 ambientLightpointLight와 같은 빛이 될 수도 있고
Stars와 같은 기본으로 제공되는 3d 물체일 수도 있는데
이건 찾아보면 다 나옴

GLTF를 이용해 Model 만들기

문제는 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>
    );
}

Model 회전 주기

아래의 링크를 참고했다.
https://onion2k.github.io/r3f-by-example/examples/hooks/rotating-cube/

우리는 box와 같은 단일 물체가 아닌 group을 사용하기에
useFrame 안에 grouprotation.x(y) 값을 넣어주면 된다.

그런 후 JSX의 가장 상위 group의 props에 rotation-x(y)를 추가해주면 됨

Model 크기 조절

방법이 다양한 것 같기는 한데, 일단 가장 간단한건 캔버스 카메라 위치조정이다.

<Canvas camera={{ position: [0, 0, 3] }}>
    <Model />
    <OrbitControls />
</Canvas>

위에처럼 카메라 프로퍼티에 position을 z축을 0을 주면 가장 가까이 붙는거고
숫자를 높일 수록 카메라 z축이 증가하니, 물체에서 멀어지고, 결국 물체가 작아진다고 보면 된다.

0개의 댓글