背景
背景が変化するリッチなWebサイトをよく見かけます。
Three.jsでは3DモデルをWeebページ上に表示できるので、2Dでは表現できないようなリッチな背景をWebサイトに実装する事ができます。
ReactでもThree.jsのようなライブラリがないか調べたところ、three.js の React レンダラーであるreact-three-fiberがありました。
本記事では、react-three-fiberを使用し、Blenderで制作した3Dモデルをwebページ上に表示してみます。
◆完成イメージ図
- react-three-fiber
- drei
前提
本記事では、React×TypeScript環境を使用します。
また、Blenderで作成した3Dモデルの準備が必要です。
Blenderで設定したブルームの表現については触れず、
3DモデルをWebサイト上に表示させるところに絞っています。
環境
- Blender:3.4
- Typescript:4.9.5
- React:18.2.0
- React-three-drei:9.88.11
- React-three-fiber:8.15.9
準備する3Dモデル
今回は桜をイメージした次の3Dモデルを表示させてみます。
Blender側ではgltf形式でエクスポートしました。
設定は以下の通りです。
1. プロジェクトの作成
--template typescript
を付けて、TypeScriptを使用するプロジェクトのひな形を作成します。
コマンドは以下の通りです。
npx create-react-app プロジェクト名 --template typescript
2. ライブラリインストール
react-three-fiberとdreiを以下のコマンドでインストールします。
npm i three @react-three/fiber @react-three/drei
以下のコマンドでthreeの型定義モジュールをインストールします。
npm i -D @types/three
- 参考:https://docs.pmnd.rs/react-three-fiber/getting-started/installation
- 参考:https://www.npmjs.com/package/@types/three?activeTab=versions
3. フォルダ構成
一部分のみですがフォルダ構成は、以下の通りです。
assetsフォルダにBlenderでエクスポートした3Dモデル(sakura_tree.glb)を追加しています。
┬public
│ └assets
│ └sakura_tree.glb
└ src
├css
│ └index.css
├App.tsx
└index.tsx
4. GLTF形式の3Dモデルを読み込み
以下のコード部分では、useGLTF
フックを使用してGLTF形式の3Dモデルを読み込み、
そのモデルのscene
を作成しています。
<primitive>
コンポーネントを使用して、作成したシーンを描画しています。
function Model() {
const { scene } = useGLTF("assets/sakura_tree.glb")
return <primitive object={scene} />
}
5. キャンバスの描画
以下のコード部分では、<Canvas>
コンポーネントを使用して3Dモデルをキャンバス内に描画しています。
キャンバスの背景色はstyle={{ background: "#001122" }
でネイビー色を指定しています。
camera
プロパティを使用してカメラの初期位置を指定しています。
export default function App() {
return (
<>
<Canvas camera={{ position: [2, 1, 2], near: 0.05 }}
style={{ background: "#001122" }>
{/* ~ */}
</Canvas>
</>
)
}
6. 3Dモデルの描画
<OrbitControls>
コンポーネントによりマウス操作でカメラの回転やズームを制御できます。
autoRotate
プロパティが設定されているためカメラは水平方向に自動で回転します。
また、<group>
コンポーネント内にModel
コンポーネントを配置し3Dモデルを描画しています。
export default function App() {
return (
<>
<Canvas camera={{ position: [2, 1, 2], near: 0.05 }}
style={{ background: "#001122" }>
{/* 3Dモデルの表示 */}
<group>
<Model />
</group>
{/* 自動横回転 */}
<OrbitControls autoRotate />
{/* フレームレート情報 */}
<Stats />
</Canvas>
</>
)
}
補足
Stats
コンポーネントを使用する事で、画面にフレーム レート情報を表示できます。
必要ない場合は削除してください。
・App.tsxのコード全体
以上を踏まえたApp.tsx全体のコードです。
import { Canvas } from '@react-three/fiber'
import { Stats, OrbitControls, useGLTF } from '@react-three/drei'
function Model() {
const { scene } = useGLTF("assets/sakura_tree.glb")
return <primitive object={scene} />
}
export default function App() {
return (
<>
<Canvas camera={{ position: [2, 1, 2], near: 0.05 }}>
<group>
<Model />
</group>
<OrbitControls autoRotate />
<Stats />
</Canvas>
</>
)
}
・index.tsxのコード全体
root.render
メソッドを使用してidがroot
のDOM要素にレンダリングします。
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import "./css/index.css";
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
・index.cssのコード全体
ページ全体にコンポーネントを描画します。
body {
margin: 0;
overflow: hidden;
}
#root {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
7. 描画結果
ここまでできたら以下のコマンドで、次のコマンドで起動します。
npm start
実行すると以下画像のように3Dモデルをwebサイト上に表示出来ていました。
しかし、Blenderでの見え方と異なっており、3Dモデルに影がなく花びら部分がのっぺりとしたボールのようになっています。。
8. 改善:ライトの設置
ライトを設置していなかったため、影が投影されていなかった可能性がありました。
以下のコードをApp.tsxファイルのCanvas
部分に記載し、平行光源を追加します。
- directionalLight:平行光源
- position={[x, y, z]}:ライトの位置
-
castShadow
プロパティ:影の投影
{/* ライト */}
<directionalLight position={[5, 5, 5]} castShadow />
ライトを追加したApp.tsxは以下の通りです。
<Canvas camera={{ position: [2, 1, 2], near: 0.05 }} style={{ background: "#001122" }}>
{/* 3Dモデルの表示 */}
<group>
<Model />
</group>
{/* 自動横回転 */}
<OrbitControls autoRotate />
{/* 統計情報 */}
<Stats />
{/* ライト */}
<directionalLight position={[5, 5, 5]} castShadow />
</Canvas>
平行光源を追加した事で、追加前に比べて花びら1枚1枚がよりはっきり見えるようになりました。
上記改善よりましにはなりましたが、
Blenderで3Dモデルに設定していたブルーム感がまだ反映されません。。
本記事では、react-three-fiberで3DモデルをWebサイト上に表示する事が目的でだったので、
一端ここまでとします。
ブルーム感を出す方法については、次の記事に続きます。
- 次の記事:react-three-fiberで表示した3Dモデルに発光感(ブルーム)を付ける