最近、AIを使った3Dモデルの生成が驚くほど簡単になりました。中でも「Meshy」というAIツールは、直感的な操作で高品質な3Dモデルを素早く生成できます。
今回のブログでは、Meshyを使って生成した3Dモデルを、ReactとThree.jsでブラウザに表示する方法を解説します!
📺 Meshyを確認する:こちらのリンクから公式ページで確認できます。
初心者でも安心して挑戦できるシンプルな手順なので、ReactやThree.jsを使った開発に興味がある方は、ぜひ最後までご覧ください!
TypeScript x React Three Fiberのレッスンや作品は、今後もどんどん作成していきます!
YouTubeで告知致しますので、ぜひYouTubeのチャンネル登録をして通知をお待ちください!
📺 YouTubeを見る:こちらのリンクから視聴できます。
React Three Fiberで何ができるのか知りたい方は、下記を参考にしてみてください!
簡単にできる作品を用意しております!
3Dモデル表示のデモ
以下の動画で、完成形のデモを見ることができます。
📺 YouTubeでデモを見る:こちらのリンクから視聴できます。
さらに、このプロジェクトのソースコードはGitHubに公開しています。
ぜひコードをダウンロードして試してみてください!
💾 GitHubリポジトリ:こちらのリンクでソースコードをチェック!
「見てみたけどどうやって作るの?」と思った方、安心してください!
この記事では、この3Dモデルを表示する方法をステップバイステップで解説していきます。
必要な技術と主要ライブラリ
このプロジェクトでは、以下の技術とライブラリを使用しています。それぞれの役割を簡単に説明します。
- React
- フロントエンド開発のためのライブラリ
- コンポーネントベースの設計でUIを効率的に構築できます
- Three.js
- 3DグラフィックスをWeb上で描画するためのライブラリ
- WebGLの複雑な処理を簡単に扱えるようにしてくれます
- React Three Fiber
- ReactでThree.jsを扱うためのラッパーライブラリ
- Reactの開発スタイルでThree.jsの強力な機能を利用できます
- React Thee Drei
- React Three Fiberの拡張ライブラリ
- React Three Fiberの拡張ライブラリ
- Meshy
- AIを活用して高品質な3Dモデルを簡単に生成できるサービス
実装の全体設計
このプロジェクトでは、「AIツールを使って3Dモデルを生成し、ReactとThree.jsでブラウザ上に表示する」というシンプルな流れを実現します。
- モデルの読み込み
-
- ReactとThree.jsを使い、生成した3Dモデルをプロジェクト内にインポートします。
OBJLoader
とMTLLoader
を用いて、Three.jsシーン内にモデルを表示します。
- HTML要素の追加(画面部)
-
- Dreiライブラリの
Html
コンポーネントを使用して、3Dモデルのモニター部分にログインフォームを表示します。 - フォームはHTML/CSSでスタイリングします。
- Dreiライブラリの
- カメラ操作と背景デザイン
-
- カメラの移動を横方向のみに制限し、ユーザーがモデルを適切に閲覧できるよう調整します。
- 背景にはグラデーションを設定し、ビジュアル的な魅力を向上させます。
環境準備
このセクションでは、プロジェクトの初期設定を行います。npxコマンドでReactアプリを作成し、必要なライブラリをインストールしてフォルダ構成を整えます。
Reactアプリの作成
まず、npxコマンドを使用してReactアプリを作成します。
npx create-react-app meshy-3d-model --template typescript
meshy-3d-model
はプロジェクトの名前です--template typescript
を指定することで、TypeScript対応のテンプレートを使用します
必要なライブラリのインストール
React Three Fiberやその他のライブラリをインストールします。
cd meshy-3d-model
npm install three @react-three/fiber @react-three/drei
- three: Three.js本体
- @react-three/fiber: ReactでThree.jsを使うためのラッパー
- @react-three/drei: カメラコントロールやテキスト描画など、便利なヘルパー
フォルダ構成の見直しと不要ファイルの削除
初期状態から以下のようにフォルダを整理・追加します。
基本的には初期値だったりしますが、わからないファイルなどは、GitHubを見てみてください。
meshy-3d-model/
├── node_modules/
├── public/
│ ├── models/ // 3Dモデルと関連ファイル
│ │ ├── monitor.obj // Meshyで生成したOBJファイル
│ │ ├── monitor.mtl // Meshyで生成したMTLファイル
│ │ └── texture.png // 必要に応じて追加するテクスチャ
├── src/
│ ├── components/ // 他のコンポーネントを追加する場合のディレクトリ
│ ├── data/ // 必要ならデータを管理するファイル用
│ ├── pages/ // ページ単位で管理するコンポーネント
│ │ ├── Meshy3DModel/
│ │ │ ├── Meshy3DModelPage.tsx // メインページのコード
│ │ │ └── Meshy3DModelPage.css // スタイルシート
│ ├── App.tsx // アプリのエントリーポイント
│ ├── index.tsx // Reactのレンダリング処理
│ ├── App.css // グローバルスタイル
│ ├── index.css // グローバルCSS
├── package.json
├── tsconfig.json // TypeScriptの設定
└── README.md // プロジェクト概要
今回手を加えるファイルは、下記となります。
App.tsx
: アプリのエントリーポイントpages/Meshy3DModel
: 今回作成対象のフォルダMeshy3DModelPage.tsx
: メインページのコンポーネント。
各ステップ毎にソースコードの詳細解説
以下のセクションでは、下記の5つのPARTを順番に詳しく解説していきます。
- Meshyを利用して、AIで3Dモデルを生成します
CAMERA_POSITION
、MONITOR_SCALE
など、3Dモデルの表示やカメラ操作に必要な基本的な定数を定義しますHTML_POSITION
やHTML_ROTATION
を設定することで、モニター内のHTML要素(フォーム)の位置と向きを調整しています
MTLLoader
とOBJLoader
を使用して、Meshyで生成した3Dモデルとテクスチャを読み込みますprimitive
を用いてモデルを描画します- Dreiライブラリの
Html
コンポーネントを使用し、モニター部分にログインフォームを配置します position
、rotation
、scale
でHTML要素の見た目を微調整
- React Three Fiberの
Canvas
を使って3Dシーンを作成します - モデルのレンダリングやカメラ設定を行います
- CSSの
linear-gradient
を使用して、視覚的な魅力を向上させる背景デザインを適用します OrbitControls
を使用し、カメラの動きを横方向(左右)のみに制限しています- モニターを正面から見やすくする設定です
全体ソースを確認
以下は、この記事で作成する爆発する3Dボタンの完成版ソースコードです。すべてのコードをまとめていますので、動作のイメージをつかみやすいと思います。
これ以外のソースを見たい方は、GitHubで確認してください。
import './App.css';
import { Meshy3DModel } from './pages';
function App() {
return (
<div className="App">
<Meshy3DModel />
</div>
);
}
export default App;
import React from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Html } from "@react-three/drei";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import { useLoader } from "@react-three/fiber";
import * as THREE from "three";
// ================================
// PART 1: 定数定義
// ================================
const CAMERA_POSITION = new THREE.Vector3(0, 0, 3); // Vector3形式でカメラ位置を定義
const MONITOR_SCALE = 1;
const MONITOR_ROTATION = [0, -Math.PI / 2, 0];
const HTML_POSITION = new THREE.Vector3(0, 0.15, 0.06);
const HTML_ROTATION = new THREE.Euler(-0.075, 0, 0);
const HTML_SCALE = new THREE.Vector3(2.45, 1.85, 0.5);
// ================================
// PART 2: モニターディスプレイコンポーネント
// ================================
const MonitorDisplay: React.FC = () => {
const materials = useLoader(MTLLoader, "/models/monitor.mtl");
const obj = useLoader(OBJLoader, "/models/monitor.obj", (loader) => {
materials.preload();
loader.setMaterials(materials);
});
return (
<>
{/* モニターモデル */}
<primitive
object={obj}
scale={MONITOR_SCALE}
position={[0, 0, 0]}
rotation={MONITOR_ROTATION}
/>
{/* HTML要素(ディスプレイ部分) */}
<Html
transform
position={HTML_POSITION}
distanceFactor={1}
occlude
scale={HTML_SCALE}
rotation={HTML_ROTATION}
>
<div
style={{
width: "300px",
height: "200px",
background: "white",
borderRadius: "10px",
boxShadow: "0 0 10px rgba(0,0,0,0.5)",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
padding: "10px",
textAlign: "center",
}}
>
<h2>Login</h2>
<input
type="text"
placeholder="Username"
style={{ marginBottom: "10px", padding: "5px" }}
/>
<input
type="password"
placeholder="Password"
style={{ marginBottom: "10px", padding: "5px" }}
/>
<button
style={{
padding: "10px 20px",
background: "blue",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
Submit
</button>
</div>
</Html>
</>
);
};
// ================================
// PART 3: メインコンポーネント
// ================================
const Meshy3DModel: React.FC = () => {
return (
<div
style={{
width: "100vw",
height: "100vh",
background: "linear-gradient(135deg, #1e3c72,rgb(78, 126, 211))", // グラデーション
}}
>
<Canvas camera={{ position: CAMERA_POSITION, fov: 60 }}>
<ambientLight intensity={20} />
<spotLight position={[10, 10, 10]} intensity={2} />
{/* モニターディスプレイ */}
<MonitorDisplay />
{/* カメラ操作を制限 */}
<OrbitControls
minPolarAngle={Math.PI / 2}
maxPolarAngle={Math.PI / 2}
/>
</Canvas>
</div>
);
};
export default Meshy3DModel;
PART 1: Meshyで3Dモデルの生成
今回、3Dモデルは、MeshyというAI自動生成サービスを利用します。
リンクは、下記になりますので、参考にしてみてください。
毎月200クレジット分は、無料で利用可能です。
📺 Meshyを確認する:こちらのリンクから公式ページで確認できます。
テキスト生成モデル>プロントで生成したい3Dモデルを記載して、「生成する」ボタンを押下します。
生成されると、4種類の3Dモデルが提示されます。好みの3Dモデルがあれば、「選択>確認する」を選択します。
そうすると、テクスチャがついて3Dモデルが生成されます。
このままで問題なければ、ダウンロードしますが、今回はテクスチャを変えてみようと思います。
右枠からテクスチャ>プロンプトに希望のテクスチャを設定して、「テクスチャ」ボタンを押下します。
画面のところまで、アルミニウムになってしまいましたが、画面はThreejsでHTMLを入れますので、これでOKとします。
ダウンロードボタンを押下して、フォーマット:objでダウンロードします。
obj、mtl、pngがダウンロードされると思います。
日本語名でダウンロードされる場合は、適当に英語に直しておきましょう。
ファイル名を変更した場合、objファイルとmtlファイルの一部を修正する必要があります。
元々のファイル名のところを、修正後のファイル名に書き換えてください。
# Blender 3.6.0
# www.blender.org
mtllib monitor.mtl
o monitor
v 0.094246 -0.375423 0.989129
v 0.097641 -0.373034 0.989317
v -0.123948 -0.629135 0.100659
v -0.131537 -0.624742 0.092791
v -0.143337 -0.627172 0.117533
v -0.003185 0.139220 -0.023328
v -0.012956 0.138576 -0.022627
v -0.016497 0.138405 -0.006704
v -0.006145 0.139249 -0.006801
v -0.178673 -0.664484 -0.063357
v -0.171106 -0.666965 -0.065225
v -0.169799 -0.666526 -0.041548
v 0.026336 0.143811 -0.053985
v 0.042294 0.007904 0.501178
v 0.044668 -0.020894 0.503462
v 0.043755 -0.024969 0.525789
・・・
# Blender 3.6.0 MTL File: 'None'
# www.blender.org
newmtl Material.001
Ns 250.000000
Ka 1.000000 1.000000 1.000000
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.450000
d 1.000000
illum 2
map_Kd monitor.png
これで3Dモデルの生成は完了です。
PART 1: 定数定義
まずは、各ライブラリのimportと、定数定義です。
import React from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls, Html } from "@react-three/drei";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
import { useLoader } from "@react-three/fiber";
import * as THREE from "three";
// ================================
// PART 1: 定数定義
// ================================
const CAMERA_POSITION = new THREE.Vector3(0, 0, 3); // Vector3形式でカメラ位置を定義
const MONITOR_SCALE = 1;
const MONITOR_ROTATION = [0, -Math.PI / 2, 0];
const HTML_POSITION = new THREE.Vector3(0, 0.15, 0.06);
const HTML_ROTATION = new THREE.Euler(-0.075, 0, 0);
const HTML_SCALE = new THREE.Vector3(2.45, 1.85, 0.5);
生成した3Dモデルによっては、微調整が必要だと思いますので、下記を参考に数字をいじってみてください。
- カメラ位置の定義
CAMERA_POSITION
: カメラの初期位置を定義します- カメラをモニターの正面に配置するために、
new THREE.Vector3(0, 0, 3)
を設定しています - これにより、ユーザーがモニターを適切に正面から閲覧できるようにします
- カメラをモニターの正面に配置するために、
- モニターのスケールと回転の定義
MONITOR_SCALE
: モニター全体の拡大縮小率を調整します- 値を変更することで、モデルのサイズを簡単に変更できます
MONITOR_ROTATION
: モニターの向きを指定します[0, -Math.PI / 2, 0]
と設定し、モニターを正面に向けています
- HTML要素の位置、回転、スケールの定義
HTML_POSITION
: HTML要素(ログインフォーム)の位置を定義します- モニターの画面部分に配置するために、座標を微調整しています
HTML_ROTATION
: HTML要素の回転を調整します- モニターに少し傾斜がある場合でも、画面内で適切に見えるように調整します
HTML_SCALE
: HTML要素のサイズを定義します- モニターの画面に収まるようにスケールを設定しています
PART 2: モニターディスプレイコンポーネント
PART 2では、Meshyで生成した3Dモデルを読み込み、モニターとディスプレイを構築します。また、DreiのHtml
コンポーネントを使用して、モニターの画面部分にHTML要素(ログインフォーム)を配置します。
// ================================
// PART 2: モニターディスプレイコンポーネント
// ================================
const MonitorDisplay: React.FC = () => {
const materials = useLoader(MTLLoader, "/models/monitor.mtl");
const obj = useLoader(OBJLoader, "/models/monitor.obj", (loader) => {
materials.preload();
loader.setMaterials(materials);
});
return (
<>
{/* モニターモデル */}
<primitive
object={obj}
scale={MONITOR_SCALE}
position={[0, 0, 0]}
rotation={MONITOR_ROTATION}
/>
{/* HTML要素(ディスプレイ部分) */}
<Html
transform
position={HTML_POSITION}
distanceFactor={1}
occlude
scale={HTML_SCALE}
rotation={HTML_ROTATION}
>
<div
style={{
width: "300px",
height: "200px",
background: "white",
borderRadius: "10px",
boxShadow: "0 0 10px rgba(0,0,0,0.5)",
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
padding: "10px",
textAlign: "center",
}}
>
<h2>Login</h2>
<input
type="text"
placeholder="Username"
style={{ marginBottom: "10px", padding: "5px" }}
/>
<input
type="password"
placeholder="Password"
style={{ marginBottom: "10px", padding: "5px" }}
/>
<button
style={{
padding: "10px 20px",
background: "blue",
color: "white",
border: "none",
borderRadius: "5px",
cursor: "pointer",
}}
>
Submit
</button>
</div>
</Html>
</>
);
};
- モニターモデルの読み込み
OBJLoader
とMTLLoader
を使用してモデルを正確に描画primitive
を利用してThree.jsのシーンに統合
- HTMLと3D空間の統合
- Dreiの
Html
コンポーネントで、3D空間内にHTML要素を配置 position
やscale
を調整することで、モニターの画面にぴったり収まるように配置
- Dreiの
PART 3: メインコンポーネント
PART 3では、React Three FiberのCanvas
を使用して3Dシーンを構築し、モニターディスプレイを表示します。また、背景デザインやカメラ操作の制限を設定して、全体の見た目や操作性を整えます。
// ================================
// PART 3: メインコンポーネント
// ================================
const Meshy3DModel: React.FC = () => {
return (
<div
style={{
width: "100vw",
height: "100vh",
background: "linear-gradient(135deg, #1e3c72,rgb(78, 126, 211))", // グラデーション
}}
>
<Canvas camera={{ position: CAMERA_POSITION, fov: 60 }}>
<ambientLight intensity={20} />
<spotLight position={[10, 10, 10]} intensity={2} />
{/* モニターディスプレイ */}
<MonitorDisplay />
{/* カメラ操作を制限 */}
<OrbitControls
minPolarAngle={Math.PI / 2}
maxPolarAngle={Math.PI / 2}
/>
</Canvas>
</div>
);
};
export default Meshy3DModel;
- 3Dシーンの作成
camera
の初期設定position
:CAMERA_POSITION
を使用して、カメラをモニターの正面に配置fov
: 視野角(Field of View)を設定(今回は60に設定)
- ライトの追加
ambientLight
(環境光)- シーン全体を均一に照らすライト
intensity
を高め(20に設定)、モデルの細部が見えるようにします
spotLight
(スポットライト)- 特定の方向からモデルを照らすライト
position
でライトの位置を調整し、モニターが適切に強調されるように設定
- モニターディスプレイの配置
- PART 2で作成した
MonitorDisplay
コンポーネントを呼び出して、モニターとディスプレイを配置します
- PART 2で作成した
- カメラ操作の制限
- 操作を横方向のみに制限
minPolarAngle
とmaxPolarAngle
をMath.PI / 2
に設定し、カメラの上下移動を無効化(※HTMLがうまく上下で隠れなかったため)- モニターが常に正面から見えるようにします
- ズームの調整
- 今回はカメラのズーム機能をデフォルトのまま使用していますが、
enableZoom
を使用して有効/無効を切り替えることも可能です
- 今回はカメラのズーム機能をデフォルトのまま使用していますが、
- 操作を横方向のみに制限
- 背景の設定
- 3Dシーン全体の背景にはCSSの
linear-gradient
を使用して、グラデーションを適用します
- 3Dシーン全体の背景にはCSSの
最後に
ここまでで、Meshyを使った3Dモデルの生成から、React×Three.jsを使用してブラウザに表示するまでの手順を解説しました。このプロジェクトは、3DモデリングやThree.jsに初めて触れる方でも簡単に実現できるよう設計されています。
- MeshyでAI生成した3Dモデルを活用
- React×Three.jsの統合
- インタラクティブなHTML要素の追加
- 視覚的な工夫
Meshyを利用して、様々な3Dモデルを表示してみてください!
📺 YouTubeでデモを見る:こちらのリンクから視聴できます。
このチュートリアルが役に立ったと感じたら、ぜひYouTubeのチャンネル登録&高評価お願いいたします!
さらに、このプロジェクトのソースコードはGitHubに公開しています。
ぜひコードをダウンロードして試してみてください!
💾 GitHubリポジトリ:こちらのリンクでソースコードをチェック!
参考になった方は、是非チャンネル登録をお願いします!
TypeScript x React Three Fiberのレッスンや作品は、今後もどんどん作成していきます!
YouTubeで告知致しますので、ぜひYouTubeのチャンネル登録をして通知をお待ちください!
📺 YouTubeを見る:こちらのリンクから視聴できます。
React Three Fiberで何ができるのか知りたい方は、下記を参考にしてみてください!
簡単にできる作品を用意しております!