😄
@react-threeで簡単なオブジェクトを作ってみるメモ
@react-threeで簡単なオブジェクトを作ってみるメモ
サンプルの物をちょっといじっただけですが(;^ω^)
各コンポーネントについて
Three.js関連のもののみ調べました
Canvas
- シーン、レンダラーをカプセル化したコンポーネント
- 子コンポーネントにカメラやライト、メッシュを配置することができる
- 親要素の幅、高さに従う
<Canvas>
{children}
</Canvas>
OrbitControls
- カメラを操作することができる
- minDistance: ドリー・イン(カメラが被写体に近づく意味=視点が前進)できる距離
- maxDistance: ドリー・アウト(カメラが被写体から離れる)できる距離
<OrbitControls minDistance={12} maxDistance={200} />
mesh
- 3Dオブジェクトを表示するコンポーネント
- three.jsのTHREE.Mesh()に相当し、JSX要素として呼び出すことができる
なぜグローバルに扱えるのかは今後調べる
<mesh>
{children}
</mesh>
sphareGeometry
- 球面のジオメトリを定義する
- argsは左から順に
- 半径: 球体の大きさを定義する。
- 幅セグメント : 水平方向の分割数を定義しているらしい。値が大きいほど滑らかになるが、処理負荷も増える
- 高さセグメント: 垂直方向の分割数。上に同じく。
<sphereGeometry
args={[3, 64, 64]}
/>
capsuleGeometry
- カプセル型のジオメトリを定義する
- argsは左から順に
- 半径: カプセルの半径を定義する。
- 高さ: 円筒部分の高さを定義する。
- キャップセグメント : カプセルの両端の半球部分の分割数を定義しているらしい。値が大きいほど滑らかになるが(ポリゴン数も増加)、処理負荷も増える
- 放射状セグメント: カプセルの周囲方向の分割数を定義。上に同じく。
<capsuleGeometry
args={[1, 5, 64, 64]}
/>
meshStandardMaterial
- 物理ベースのレンダリング原理(PBR?)に基づいたマテリアル
- 光学的性質をシミュレートする
- color: 色を指定。デフォルトは"white"。16進数のカラーコードを指定することで色を変えられる。
- リアルな反射や屈折を表現することができる
- roughness: 粗さ。0.0 ~1.0の間で指定する
- metalness: 金属度
<meshStandardMaterial
color={"hotpink"}
metalness={0.7}
roughness={0.5}
/>
ambientLight
- 環境光を定義する
- itensity: 光の強さ
<ambientLight intensity={Math.PI / 2} />
spotLight
-
position: スポットライトの3D空間における位置
-
値が小さいほど狭く集中した光、大きいほど拡散した光になる。→ステージのスポットライトと同じようなものなのだろうか?
-
angle: ライトのビーム角度(ラジアン)
-
penumbra: スポットライトの端(エッジ)のぼかし具合
- 0: はっきりとした硬い光の境界線
- 1: 完全にソフトな光の減衰
-
decay: 距離による光の減衰率
-
itensity: 省略
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
pointLight
-
空間の一点から全方向に均等に光を投射する光源
-
電球や電灯に近い光
-
距離減衰がある
-
position: 省略
-
decay: 省略
-
itensity: 省略
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
各光源の違い
- SpotLight(スポットライト): 特定の方向に円錐状の光を放射。舞台照明のスポットライトのような効果
- DirectionalLight(平行光源): 太陽光のように平行に進む光線を発生。方向は持つが特定の位置は持たない
- AmbientLight(環境光): 特定の方向や位置を持たず、シーン全体を均等に照らす
- HemisphereLight(半球光): 空と地面からの光を模倣し、上下で異なる色の光を放射
今回のコード
"use client"
import * as THREE from "three"
import { Canvas, ThreeElements } from "@react-three/fiber";
import { useRef } from "react";
import { OrbitControls } from "@react-three/drei";
const Ball = (props: ThreeElements["mesh"]) => {
const meshRef = useRef<THREE.Mesh>(null)
return (
<mesh
{...props}
ref={meshRef}
>
<sphereGeometry
args={[3, 64, 64]}
/>
<meshStandardMaterial
color={"hotpink"}
metalness={0.7}
roughness={0.5}
/>
</mesh>
)
}
const Medicine = (props: ThreeElements["mesh"]) => {
const meshRef = useRef<THREE.Mesh>(null)
return (
<mesh
{...props}
ref={meshRef}
>
<capsuleGeometry
args={[1, 5, 64, 64]}
/>
<meshStandardMaterial
color={"hotpink"}
metalness={0.7}
roughness={0.5}
/>
</mesh>
)
}
export default function Home() {
return (
<Canvas>
<ambientLight intensity={Math.PI / 2} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} decay={0} intensity={Math.PI} />
<pointLight position={[-10, -10, -10]} decay={0} intensity={Math.PI} />
<Ball position={[1, 0, 0]} />
<Medicine position={[6, 0, 0]} />
<OrbitControls minDistance={12} maxDistance={200} />
</Canvas>
);
}
実際の画面
metalness, roughnessあり
なし
最後に
間違っていることがあれば、コメントに書いていただけると幸いです。
よろしくお願いいたします。
Discussion