モデルの読み込みはfiberだけでもできますが、dreiを使うとさらに簡単に読み込めます。
ファイルの場所
publicファイル・・・静的ファイルとしてアクセスしたいとき
srcファイル・・・Webpackの管理下でファイルを扱いたいとき
publicフォルダに置く場合
- アクセス方法:
publicフォルダ内のファイルはURL経由で直接アクセスできます。例えば、public/models/model.gltfにファイルがある場合は、Reactのコードで/models/model.gltfのようにURLとして参照します。 - ファイル処理:
publicに置かれたファイルはWebpackのビルドプロセスに含まれず、そのままのパスで出力されます。つまり、ビルド後の構造が変わらず、ファイルが「そのままの形」で保持されます。
const { scene } = useGLTF('/models/model.gltf'); // publicフォルダにあるファイルsrcフォルダに置く場合
- アクセス方法:
srcフォルダに置く場合は、importを使ってモデルファイルをWebpackによって管理されたモジュールとしてインポートする必要があります。これはWebpackがファイルをバンドルしてくれるためで、ファイルを直接URLで参照することはできません。 - ファイル処理:
srcに置いたファイルはWebpackのビルドプロセスで処理され、依存関係としてバンドルされます。これにより、ファイルが効率的にパッケージ化され、必要なときに利用されます。つまり、publicフォルダに置いた場合と違い、ファイルのサイズ最適化やキャッシングなどのWebpackの機能が有効になります。
import modelUrl from './assets/model.gltf'; // srcフォルダにあるファイル
const { scene } = useGLTF(modelUrl);GLTFファイル形式
gltfとglbの二種類があります。
- .gltf:
テキストファイル(JSON)で、別のバイナリファイル(.bin)やテクスチャファイルを参照します。 - .glb:
全てのデータが1つのバイナリファイルにまとめられています。この形式は、配布や管理が簡単で、特にWebベースのアプリケーションで好まれます。
.gltf形式とその構成要素
- JSON形式のデータ(.gltf):
JSON形式でモデルの構成情報(メッシュ、マテリアル、アニメーション、カメラなど)を記述します。(.binファイルへのuri情報が書いてあるので、名前を変えるときはこれも変える必要有)
"buffers": [
{
"byteLength": 1840512,
"uri": "earth.bin"//.binファイルの名前が書いてある
}
],- バイナリデータ(.bin):
モデルのジオメトリ(頂点情報、インデックス、法線、テクスチャ座標など)のバイナリデータを別のファイル(通常は.binファイル)に格納します。.binファイルには、モデルのメッシュデータやアニメーションデータが含まれています。 - テクスチャファイル:
テクスチャは、.gltfファイル内に直接含めず、外部の画像ファイル(PNGやJPEG形式)として管理することが一般的です。これにより、テクスチャのサイズや圧縮方式を最適化でき、異なるテクスチャを簡単に差し替えたり、再利用したりすることができます。
モデルをjsxコンポーネントに変換する
モデルをドラッグ&ドロップでコンポーネントに一発変換してくれるサイト↓
コマンドもあります
cd public //gltfやglbがあるフォルダまで移動
npx gltfjsx model.gltf //ファイル名を指定して実行●ちなみにリンクはpublicからのリンクになってしまうので、フォルダに入れてたりするときはリンクを直す必要があります。
●export の default はついてないのでimport形式に注意。
import React from "react";
import { useGLTF } from "@react-three/drei";
export function Earth(props) {
const { nodes, materials } = useGLTF("/earth.gltf");
return (
<group {...props} dispose={null}>
<mesh
geometry={nodes.Object_4.geometry}
material={materials["Scene_-_Root"]}
scale={1.128}
/>
</group>
);
}
useGLTF.preload("/earth.gltf");上記のように、自動でuseGLTFを使ってnodeやmaterial情報を読み取り、geometryとmaterialにセットしてくれてます。素晴らしいです。
Suspense
useGLTFを使うと、reactのSuspenseコンポーネント使用時に、ローディング中にフォールバックを表示することができます。
import { Suspense } from "react";
function App() {
return (
<Canvas>
<Suspense fallback={<Html>Loading...</Html>}>
<Earth />
</Suspense>
</Canvas>
);
}fallbackの内容は直接HTML要素はおけないので、dreiのコンポーネント<Html>で挟む必要があります。(挟んだらdivとかも使えます)

