언어·프레임워크/Next.js
[Next.js] 동일한 GLTF 모델을 2번 이상 렌더링하기(react-three-fiber/drei/Three.js)
DandyNow
2023. 12. 28. 09:45
728x90
반응형
1. 한 페이지에 하나의 GLTF만 렌더링 되는 문제
페이지에 하나의 GLTF 파일을 이용해 여러 개의 모델을 렌더링 하고자 하였다. 이미지 태그를 이용하는 방식처럼 당연히 가능할 거라 생각했는데 현실은 [그림 2]와 같이 마지막 하나의 구성만 적용되었다. 여러 테스트 중에 GLTF의 복사본의 만들어 이름을 달리하여 로드했더니 원하는 결과를 얻을 수 있었다. 하지만 렌더링 모델의 개수만큼 동일한 내용을 담고 있는 GLTF 파일을 무수히 만들 수는 없는 일이었다.
2. Clone으로 문제 해결
react-three-fiber에서 Clone 컴포넌트를 제공하고 있었다. 이 기능을 이용하여 [그림 2]와 같이 하나의 GLTF를 통해 2개 이상의 모델을 화면에 렌더링 할 수 있었다.
해당 코드는 아래와 같다.
// page.tsx
"use client";
import React from "react";
import CharacterViewer from "./CharacterViewer";
export default function Page() {
const characterPath = "red_01.glb";
return (
<>
<div>
<CharacterViewer characterPath={characterPath} />
</div>
<div>
<CharacterViewer characterPath={characterPath} />
</div>
</>
);
}
// CharacterViewer.jsx
"use client";
import React, { Suspense } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { Clone, OrbitControls, useGLTF } from "@react-three/drei";
import * as THREE from "three";
const Character = ({ characterPath, scale }) => {
const { scene, animations } = useGLTF(characterPath);
let mixer = null;
// 애니메이션 재생
if (animations.length !== 0) {
mixer = new THREE.AnimationMixer(scene);
void mixer.clipAction(animations[0]).play();
// eslint-disable-next-line react-hooks/rules-of-hooks
useFrame((state, delta) => {
mixer.update(delta);
});
}
return (
<Clone object={scene} scale={scale} /> // 애니메이션 재생 안됨
// <primitive object={scene} scale={scale} /> // 애니메이션 재생됨
);
};
const CharacterViewer = ({ characterPath }) => {
return (
<div>
// Canvas에 키를 주어야 렌더링 오작동을 예방할 수 있음
<Canvas key={characterPath} camera={{ position: [20, 0, -8] }}>
<OrbitControls />
<ambientLight intensity={2} />
<pointLight position={[10, 10, 10]} />
<group {...characterPath} dispose={null} rotation-y={Math.PI / 2}>
<Character scale={[15, 15, 15]} characterPath={characterPath} />
</group>
<Suspense fallback={null}></Suspense>
</Canvas>
</div>
);
};
export default CharacterViewer;
3. 또 다른 문제
primitive 태그를 이용하면 모델의 애니메이션이 정상적으로 동작하지만, Clone 태그를 이용하면 재생되지 않는 문제가 있어 숙제가 생겼다.
참고 자료
https://stackoverflow.com/questions/68813736/use-the-same-gltf-model-twice-in-react-three-fiber-drei-three-js
728x90
반응형