LoginSignup
4
2

More than 1 year has passed since last update.

Next.js(Typescript) + Three.js(Fiber,Drei)で3Dモデルファイルを読み込んで表示するまで

Posted at

環境

  • react: 18.0.0
  • react-dom: 18.0.0
  • three: 0.139.2
  • next: 12.1.0
  • react-three/drei: 9.2.0
  • react-three/fiber: 8.0.10
  • typescript: 4.6.2

1. 導入

そもそも、この構成でやっている記事が少なく、動くようになるまで少し手間取ったため記事を書くことにしました。
もっと良い方法があったら教えて頂けると助かります。

2. 手順

①プロジェクトを作成

yarn create next-app

②各種 yarn add

③ディレクトリ構成

components/
  ┣ Model.tsx
  ┣ DrawCanvas.tsx 
pages/
  ┣ _app.tsx
  ┣ index.tsx
public
  ┣ モデルファイル

④モデル用コンポーネント定義

Model.tsx
import { useGLTF } from "@react-three/drei"

const Model = () => {
  const gltf = useGLTF('/house.glb')
  return (
    <primitive object={gltf.scene} />
  )
}

export default Model

⑤キャンバス用コンポーネント定義

DrawCanvas.tsx
import { Suspense } from 'react'
import { OrbitControls, Stage } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import dynamic from 'next/dynamic'

const Model = dynamic(() => import('../components/Model'))

const DrawCanvas = () => (
  <Suspense fallback={<span>loading</span>}>
    <Canvas>
      <OrbitControls />
      <Stage>
        <Model />
      </Stage>
    </Canvas>
  </Suspense>
)

export default DrawCanvas

⑥pageに配置

index.tsx
import type { NextPage } from 'next'
import DrawCanvas from '../components/DrawCanvas'


const Home: NextPage = () => (
  <>
    <DrawCanvas />
  </>
)

export default Home

3. 注意点

  • useGLTFなどのモデル読み込みを、キャンバスを定義するコンポーネント(DrawCanvas.tsx)のスコープの中で行うとうまく行かなかった
  • モデル用のコンポーネントを別に定義する必要がある
  • 別ファイルに定義したモデル用コンポーネントは dynamic import する必要がある
  • Suspenseを使う場合、Suspenseの中にCanvasを配置する必要がある
  • 表示されたキャンバスはデフォルトでは大きさや比率がおかしいので、cssなどでスタイリングする必要がある
4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2