three.jsは、ブラウザ上で3Dデータを扱うことのできるJavascriptライブラリです。これを使えば、ホームページなどにインパクトのある3Dキャラクターを配置したり、オリジナル3D生物をマウスでグネグネ動かしたりできるようになります(ちなみに私の"ひよこ"アイコンも実は3Dで作ってあります)。
今回はこの美しきthree.jsと、フロントエンド界の帝王Reactを組み合わせて、ブラウザ上に3Dを表示させてみたいと思います。Reactはライブラリが豊富にあり、このthree.jsを扱えるライブラリもあるのでそれを使っていきます(後述)。
とりあえず、何かしらの方法で3Dを作ります。
個人的にオススメなのはモデリングソフトの『Blender』です。無料なのに機能が非常に多く、これがあれば何にでもなれると思います。しかし、機能が多いぶんユーザーインターフェースがゴチャついているという欠点があり、ある程度の慣れが必要です。ただ、最近(というか半年前くらい?)バージョンアップしてv2.8になり、だいぶ操作しやすくなった印象です。慣れてくると「これが無料でいいのか!?」と感動すること請け合いです。
作成したら、glTFという形式でエクスポート(出力)します。
glTFというのは3Dファイルのフォーマットの一種で、簡単に言うと使い勝手のいいやつです。ファイル拡張子には .gltf と .glb という二つがありますが、.glb の方がファイルサイズを低く抑えられるのでこっちが推奨らしいです。
出力先はReactプロジェクトのpublicディレクトリにしましょう(他のディレクトリだとReact側で認識してくれないらしい…)。
※Node.jsとnpm(もしくはyarnなど)とReactがインストールされていて、かつReactプロジェクトで何かしら表示するところまでいっている前提で進めます。
まずは必要なライブラリをインストールしましょう。
npm install three react-three-fiber
ライブラリ名からも分かる通り、 react-three-fiber がthree.jsとReactを繋げてくれます。
これを使ってReactのプロジェクトに実装していきましょう。
import React, { Suspense } from 'react'
import { Canvas, useLoader } from 'react-three-fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const LoadModel = () => {
const gltf = useLoader(GLTFLoader, "/sample.glb")
return (
<primitive object={gltf.scene} dispose={null} />
)
}
const UseModel = () => {
return (
<Suspense fallback={null}>
<LoadModel />
</Suspense>
)
}
const App = () => {
return (
<Canvas>
<mesh>
<UseModel />
</mesh>
</Canvas>
)
}
LoadModelコンポーネントで3Dファイルを読み込んでいます。useLoader()の第一引数にthree.js標準のモジュールGLTFLoaderを指定して、第二引数には作成した3Dファイル(.glb)を指定しています(前述しましたが、publicディレクトリ内のファイルじゃないとエラーになります)。
UseModelコンポーネントで実際に表示させるための準備のようなことをしています。Suspenseは3Dモデルをロードしている最中に他のオブジェクトを代わりに表示しといてくれるモジュールです(公式によると現時点ではまだ実験的な機能だとのこと)。fallback={null} という箇所に本来であれば何かしらの3Dオブジェクトを入れますが、今回はシンプルに説明するためにあえてnullにしてます(つまり、ロード中には何も表示されない)。
そして最後のAppコンポーネントで表示させています。Canvasというのが3dを表示させるためのまさにキャンバスのような存在で必須です。
さあ、これで準備は整いました!
npm start とかでローカルのサーバーを立ち上げて http://localhost:3000 にアクセスしましょう。
このようにブラウザ上に表示されます。
おまけでサタデーナイトな雰囲気も演出してみました。↓
コードを改めて眺めてみるとあっさりしていますが、 react-three-fiber の情報がそこまで多くないので実は結構苦戦しました。
ご自身のブログやホームページなどがある方は、スパイス的な位置づけで3Dを活用してみるというのもアリなんじゃないでしょうか。