はじめに:「ありきたりなポートフォリオ」から脱却したいあなたへ
「ポートフォリオサイトを作ったけど、他の人と似たようなデザインになってしまう」
「Three.jsに興味があるけど、生のWebGLコードは難しそうで手が出せない」
エンジニアやデザイナーとして自分をアピールする上で、ポートフォリオサイトは非常に重要な存在です。しかし、単なるテキストと画像の並びだけでは、数多くの応募者の中で埋もれてしまいがちです。
この記事では、**React Three Fiber(R3F)**というライブラリを使い、Next.jsプロジェクトに3D表現を組み込む基礎を解説します。「WebGLは難しい」というイメージを払拭し、Reactの知識を活かして3Dオブジェクトを操作する感覚を体感していただくことがゴールです。
なぜReact Three Fiberなのか?
Three.jsは強力な3Dライブラリですが、素のJavaScriptで書くと、シーンの管理やレンダリングループの制御など、Reactのコンポーネント思考とは異質なコードになりがちです。
React Three Fiberは、Three.jsをReactのコンポーネントとして扱えるようにするレンダラーです。つまり、<mesh>や<boxGeometry>といったJSXタグを組み合わせるだけで、3Dシーンを構築できます。
- Reactの状態管理(useState, useEffect)がそのまま3D表現に使える
- コンポーネント単位で3Dオブジェクトを再利用できる
- Next.jsのページ遷移やSSRとの統合がしやすい
「Reactが書けるなら、3Dも書ける」というのがR3Fの最大の魅力です。
実際に3Dオブジェクトを表示してみる
まずは環境を整えましょう。Next.jsプロジェクトに以下のパッケージを導入します。
npm install three @react-three/fiber @react-three/drei
@react-three/dreiは、カメラ操作やライティングなど便利なヘルパーをまとめたユーティリティ集で、R3Fと組み合わせて使うのが定番です。
次に、シンプルな回転する立方体を表示するコンポーネントを作成します。
'use client'
import { Canvas } from '@react-three/fiber'
import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
function RotatingBox() {
const meshRef = useRef()
// 毎フレーム呼ばれる処理。ここでオブジェクトを回転させる
useFrame((state, delta) => {
meshRef.current.rotation.x += delta
meshRef.current.rotation.y += delta * 0.5
})
return (
<mesh ref={meshRef}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="royalblue" />
</mesh>
)
}
export default function Scene() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<directionalLight position={[2, 2, 2]} />
<RotatingBox />
</Canvas>
)
}
useFrameはR3F独自のフックで、Three.jsのアニメーションループに毎フレームアクセスできます。Reactのライフサイクルとは別の仕組みですが、useRefで参照を持っておくことで、Reactらしい書き方のまま3Dオブジェクトを制御できます。
Next.jsのApp Routerを使っている場合、Canvasを含むコンポーネントには'use client'ディレクティブが必須です。Three.jsはブラウザのWebGL APIに依存するため、サーバーサイドでは実行できない点に注意しましょう。
ポートフォリオに活かす:スクロール連動の考え方
3Dオブジェクトをただ表示するだけでは、ポートフォリオとしての魅力は半分です。ユーザーがスクロールするのに合わせてカメラやオブジェクトが動くと、体験として非常に印象的になります。
基本的な考え方はシンプルです。
-
window.scrollYやIntersection Observerでスクロール位置を取得する - その値を0〜1などの範囲に正規化する
- 正規化した値を使ってカメラの位置やオブジェクトの回転角度を補間する
import { useFrame } from '@react-three/fiber'
import { useRef } from 'react'
function ScrollControlledCamera() {
const scrollProgress = useRef(0)
useFrame((state) => {
// スクロール量に応じてカメラのZ位置を変化させる
const targetZ = 5 - scrollProgress.current * 3
state.camera.position.z += (targetZ - state.camera.position.z) * 0.1
})
return null
}
このように「スクロール量 → 数値 → 3D空間のパラメータ」という変換の考え方を理解すると、カメラワークだけでなく、オブジェクトのフェードインやパーティクルの動きなど、応用範囲は一気に広がります。
パフォーマンスへの配慮も忘れずに
3D表現は視覚的なインパクトが大きい一方、モバイル端末などでは負荷が高くなりがちです。以下の点は基礎として押さえておくと安心です。
-
<Canvas>のdprプロパティで解像度を制限し、負荷を調整する - 使わなくなった3Dオブジェクトはコンポーネントのunmountで確実に破棄する
- 複雑なモデルは
@react-three/dreiのuseGLTFとSuspenseで遅延読み込みする
これらを意識するだけで、見た目のクオリティを保ちながら快適な表示速度を実現できます。
まとめ
この記事では、React Three FiberとNext.jsを組み合わせた3D表現の基礎を解説しました。
- React Three FiberはThree.jsをReactコンポーネントとして扱えるレンダラーであること
-
useFrameを使った基本的なアニメーションの実装方法 - スクロール位置を3D空間のパラメータに変換する考え方
- モバイル環境も見据えたパフォーマンス面での配慮
3D表現は最初こそ複雑に見えますが、Reactの知識を土台にすれば着実に理解を積み上げていけます。今回紹介した回転する立方体のコードを起点に、色や形、動きを変えてみるだけでも新しい発見があるはずです。
さらに実践的なポートフォリオを作りたい方へ
今回はR3Fの基礎的な部分に絞って解説しましたが、「実際に自分のポートフォリオとして、スクロール連動の3D表現を一つの作品に仕上げたい」と感じた方もいるのではないでしょうか。
そのような場合、ゼロから実装の流れを体系的に追える教材があると、学習がスムーズに進みます。例えば「【Next.js × Three.js】React Three Fiberで作るスクロール連動型3Dポートフォリオ」という講座では、今回紹介したスクロール連動の考え方をベースに、実際に一つの3Dポートフォリオを作り上げる過程を学べる内容になっています。
「記事で得た基礎を、実際に手を動かして一つの作品に落とし込みたい」という方には、こうした教材も次のステップの選択肢の一つになるかもしれません。ぜひ自分なりの表現を、3Dの世界で形にしてみてください。