React Three Fiberについて
はじめに
WebGLを使ったWebフロントエンドを開発する機会があったので、自分の備忘録として書く。
React Three Fiberとは
ReactにThree.jsを埋め込むためのライブラリ。
Three.jsの3DオブジェクトをReactを使うことで、JSX感覚で配置することができる。
使ってみる
Reactアプリケーションを作る
npx create-react-app my-react-three-app
React Three Fiberをnpmインストール
npm install three @react-three/fiber
とりあえず、回転する立方体を作ってみる。
import React, { useRef } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { Box } from '@react-three/drei';
function SpinningCube() {
const cubeRef = useRef();
// 回転を毎フレーム更新する
useFrame(() => {
if (cubeRef.current) {
cubeRef.current.rotation.x += 0.01;
cubeRef.current.rotation.y += 0.01;
}
});
return (
<Box ref={cubeRef} args={[1, 1, 1]} position={[0, 0, 0]}>
<meshStandardMaterial color="orange" />
</Box>
);
}
function App() {
return (
<Canvas>
{/* 照明を追加 */}
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
{/* 立方体を表示 */}
<SpinningCube />
</Canvas>
);
}
export default App;
JSXに、3Dオブジェクトを配置できるので、とても便利。
特に、Reactのコンポーネントを活用することができるので、拡張性が高いものを作ることができる。
このコードがしていることは以下
Reactの機能の一つであるuseRefフックを使って、Three.jsの3Dオブジェクトへの参照を保持しておき、
もし、useStateを使って、参照を保持すると、
Three.jsのフレームごとに、Reactがレンダリングを行うので、重くなる。
そのプロパティーの一つであるrotation
の中にあるVector3
を変更するコードを、
React Three Fiberの毎フレームに実行してくれるフックを使って、実行すると、立方体がくるくる回る。
useRef
は特定のDOM要素やオブジェクトの参照を保持するためのReactフックで、レンダリング間でその値が変わらない。
一方、useFrame
はアニメーションループを実現するために、フレームごとに自動で呼び出されるフック。
Three.jsだと、rendererを追加したりと、コードがわかりづらくなる。
React Three Fiberはとても便利であることがわかる。
視点操作の設定
カメラのプリセットなどもCanvasのchildrenのなかに書き加えるだけで、
視点操作の設定もできる。
import { OrbitControls } from '@react-three/drei';
function App() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<SpinningBox />
{/* カメラをドラッグで動かすためのコントロール */}
<OrbitControls />
</Canvas>
);
}
こんな感じ。
OrbitControls
を使うことで、ユーザーはマウスを使ってシーン内のカメラを回転、ズーム、移動させることができる。
終わり
僕は、メタバースのモデルを作るときに、再利用を徹底しようと考えているので、
ドアの取手 → ドア → 教室 → フロア → 校舎
というように、
細かいモデルのコンポーネントをたくさん作って、それらを組み合わせて作っていくという予定だ。
オブジェクトをファイルごとに分けることができるのは、とても便利だと思う。
オブジェクトを再利用しやすくなり、保守性が向上する。