この記事の続きです。
@react-three/drei(以下、dreiと呼称する。)は
@react-three/fiber(以下、r3fと呼称する。)`用の便利なヘルパー関数などを提供してくれるライブラリです。このライブラリとr3fと組み合わせることで、r3fだけでは表現できなかったことが表現できるようになります。
インストール
$ npm install @react-three/drei
パーティクル
Stars
import { Stars } from "@react-three/drei";
<Stars
radius={100} // 星の点滅(拡大)度合い
depth={50} // 星の深さ
count={5000} // 星の数
factor={6} // 星の大きさ
saturation={9} // 星の彩度
speed={3} // 点滅のスピード
/>
Points、Point
import { Points, Point } from "@react-three/drei";
const pColors = ["red", "yellow", "orange", "blue", "green", "white"];
<Points limit={2000} range={1000}>
{/* limit : パーティクルの数, range : パーティクルの描画範囲 */}
<pointsMaterial vertexColors size={0.1} />
{/* lengthの値はlimitの数に合わせる */}
{Array.from({ length: 2000 }).map((_, i) => (
<Point
key={i}
position={[
MathUtils.randFloatSpread(10),
MathUtils.randFloatSpread(10),
MathUtils.randFloatSpread(10)
]}
color={pColors[Math.floor(Math.random() * (pColors.length - 1))]}
/>
))}
</Points>
MathUtils
ここで、登場したMathUtils
とはなんなのか紹介します。MathUtils
はthree.js本体のあるものです。
import { MathUtils } from "three";
OrbitControls
three.jsに存在していた手軽にカメラの動きを自動的に制御する OrbitControls がdreiに存在します。
import { OrbitControls } from "@react-three/drei";
<OrbitControls />
この<OrbitControls />
を使用する事によりマウスでオービット(周回軌道)できたり、マウスホイールでズームなどの操作ができます。
雲を表現する
Sky
この<Sky />
を使用すると背景に「空」が描画されます。
import { Sky } from "@react-three/drei";
<Sky />
Cloud
パーティクルベースの「雲」が描画されます。
import { Cloud } from "@react-three/drei";
<Cloud
position={[0, 0, 0]} // 雲のポジショニング
opacity={0.5} // 不透明度
speed={0.4} // 回転速度
width={10} // 雲全体の幅
depth={1.5} // Z方向の深さ
segments={20} // パーティクルの数
/>
3Dモデルを表示する
blender
などで作成した3DモデルをWeb上に描画します。
描画する際には、useGLTF()
関数を使用します。
import { useGLTF } from "@react-three/drei";
const reactLogo = useGLTF(
"https://vazxmixjsiawhamofees.supabase.co/storage/v1/object/public/models/react-logo/model.gltf"
);
useGLTF()
関数の引数に任意のパスを記述します。
※モデルはここから持ってきました。
<primitive object={reactLogo.scene} position={[0, -1.3, 0.3]} scale={[1.5, 1.5, 1.5]} />
// object : useGLTF()で読み込んだモデル.scene
// position : モデルのポジショニング
// scale : モデルの拡大度合い
ContactShadows
モデルに影をつけるコンポーネント
import { ContactShadows } from "@react-three/drei";
<ContactShadows position-y={-2.0} opacity={0.7} scale={7} blur={2.4} color={"#000"} far={10} resolution={256} />
// position-y : 影の向き(y)※デフォルトでは上向き
// opacity : 影の透過度
// scale : 影の拡大度合い
// blur : 影のぼかし具合
// color : 影の色
// far :
// resolution : 影の解像度
Float
このコンポーネントを使用するとでものような浮いてるような表現ができます。
import { Float } from "@react-three/drei";
<Float
speed={1} // 回転速度。デフォルトでは1
rotationIntensity={1} // 回転強度。デフォルトでは1
floatIntensity={1} // 上下の Float の強度。デフォルトでは1
floatingRange={[1, 10]} // オブジェクトが浮動する Y 軸値の範囲。デフォルトは [-0.1,0.1]
>
<mesh />
</Float>
Text
文字を表示するコンポーネント
import { Text } from "@react-three/drei";
<Text
color={"black"} // 文字の色
anchorX={"center"} //
anchorY={"middle"} //
position={[0, 0, 0]} //文字のポジショニング
>
hello world!
</Text>
PresentationControls
スナップバックなどを備えたSemi-OrbitControlsです。
これらのコントロールは カメラを回転させませんが、コンテンツを回転させます 。OrbitControl のように限界に達したときに突然停止するのではなく、停止位置をスムーズに予測します。
import { PresenrionControls } from "@react-three/drei";
<PresentationControls
enabled={true} // これを false に設定するとコントロールを無効にできる。
global={false} // これを true に設定するとグローバルに回転する。
cursor={true} // ドラッグ時にカーソルのスタイルを切り替える。
config={{ mass: 1, tension: 170, friction: 26 }} // スプリングの設定。
snap={false} // 中央にスナップバックします。指定方法は config と同じ。
speed={1} // カメラを操作した時のモデルの動きの速度。
zoom={1} // 極最大値の半分に達したときのズーム倍率
rotation={[0, 0, 0]} // デフォルトの回転度合い
polar={[0, Math.PI / 2]} // 垂直方向の制限
azimuth={[-Infinity, Infinity]} // 水平方向の制限
domElement={events.connected} // このコントローラの DOM 要素イベントがアタッチされます。
>
<mesh />
</PresentationControls>
テクスチャ
ジオメタリに画像(テクスチャ)を貼る方法をご紹介します。useTexture()
と呼ばれるものがdreiに存在するため、使用します。
import { useTexture } from "@react-three/drei";
const maping = useTexture("画像パス");
return <meshStandardMaterial map={texture} />
パララックス
r3fを使えば、パララックスっぽいことも簡単に実現することができます。
useThree()
dreiではなくr3fにあるHooks。
デフォルトのレンダラー、シーン、カメラなどが含まれる状態モデルにアクセスできます。また、画面内のキャンバスの現在のサイズとビューポートの座標も表示されます。
import { useThree } from '@react-three/fiber'
function Foo() {
const { whidth, height } = useThree((state) => state.viewport);
ビューポートの width と height を取得する例です。
docs
Image
シェーダーベースの画像コンポーネント
import { Image } from "@react-three/drei";
<Image
url="画像パス"
scale={[1, 1, 1]} // 画像の拡大度合い
position={[0, 0, 0]} // 画像のポジショニング
transport
opacity={1} // 画像の不透明度
/>
ScrollControls、Scroll
スクロールをすることが可能になるコンポーネント。
import { ScrollControls, Scroll } from "@react-three/drei";
<ScrollControls
pages={2} // スクロール量。
damping={2} // 慣性。
horizontal={false} // true にすると横スクロール。
infinite={false} // true にすると無限スクロール(ループ)。
eps={0.00001} // スクロールの精度。デフォルトでは、0.00001。
distance={0.2} // 秒単位の摩擦。デフォルトでは、0.2。
maxSpeed={0.1} // 速度を 1 秒あたり 0.1 単位に固定
>
<Scroll>
<Images />
</Scroll>
<Scroll html>
<h1 style={{ position: "absolute", top: "60vh", left: "1.5em" }}>
Hello
</h1>
<h1 style={{ position: "absolute", top: "140vh", left: "20vw" }}>
Would!!
</h1>
</Scroll>
</ScrollControls>
<Scroll />
で html をラップする際は<Scroll html />
とする。
useScroll()
現在のスクロールなどの有用なデータを提供するフック
import { useScroll } from "@react-three/drei";
const Images = () => {
const { height } = useThree((state) => state.viewport);
const group = useRef({} as any);
const data = useScroll();
useFrame(() => {
group.current.children[0].material.zoom = 1 + data.range(0, 1 / 3) / 3;
group.current.children[1].material.zoom = 1 + data.range(0, 1 / 3) / 3;
group.current.children[2].material.zoom =
1 + data.range(1.15 / 3, 1 / 3) / 3;
group.current.children[3].material.zoom =
1 + data.range(1.15 / 3, 1 / 3) / 3;
});
return (
<group ref={group}>
<Image
url="画像パス"
scale={[4, height, 1]}
position={[-1, 0, 1]}
/>
<Image
url="画像パス"
scale={3}
position={[2, 0, 1]}
/>
<Image
url="画像パス"
scale={[1, 2.7, 1]}
position={[-2.3, -height, -2]}
/>
<Image
url="画像パス"
scale={[1.4, 2, 1]}
position={[1.3, -height - 0.3, 1.2]}
/>
</group>
);
};
export default Images;
さいごに
いかがでしたか?このように、r3fとdreiを組み合わせることで表現できることが増えるので、r3fを使用する際にはdreiと一緒に使ってみてください。
また。dreiにあるメソッドの数は膨大にあるため、紹介しきれなかったものに関してはドキュメントを読むなりしながら各自で調べてみてください。
最後まで読んでいただいてありがとうございました。