🌏

Three.js(React-three-fiber)を使って地球を作る!

2023/08/13に公開

はじめに

FrightRadar24みたいな奴を3Dで作る!という事で、まずは地球を生み出して創造主になろうと思います。
環境はNext.js + Three.js + React-three-fiberです。
サポートライブラリでdreiも使っています。カメラ制御とか色々便利な物が入っています。

地球を作るぞ

球を表示する

"use client"
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
export default function BaseGL() {
    return (
        <main style={{width: "100vw", height: "100vh"}}>
            <Canvas>
                <color attach="background" args={['#050505']} />
                <ambientLight intensity={3}/>
                <OrbitControls minDistance={101} maxDistance={200} rotateSpeed={0.4} zoomSpeed={0.5}/>
                <mesh castShadow position={[0, 0, 0]}>
                    <sphereGeometry args={[100, 128, 64]}/>
                    <meshPhysicalMaterial/>
                </mesh>
            </Canvas>
        </main>
    );
}

こーなります

上記のコードのポイントは以下です

  • 背景色は黒に。
  • 球の半径は100にしておきます。この後 緯度、経度など細かい数値を扱うので計算しやすい(人間が)かつ誤差が生まれにくいように100にしました。
    千とか一万でもいいんだろうけど、なんか怖いので(処理重くならない?)100に抑えています。(調べろよな)
  • orbitControlsを設定するとドラッグ操作だったりズームができる様になります。
    原点を中心にカメラがぐりぐり移動するので、今回はこれが最適だと思います。
    またmin,maxDistanceをいじるとzoomの最大最小を制限できます。
  • ライトはとりあえずambientLightだけ設定しておきます。
    太陽としてのdirectionalLightは今は置いておきます。正確な場所を計算して、時間で動かしたりしないといけないし、夜の面を作るの大変なので最後に余裕があったら実装してみます。

地球のテクスチャを貼る

"use client"
import { Canvas, useLoader } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
+import { TextureLoader } from "three";
export default function BaseGL() {
+   const earthMap = useLoader(TextureLoader,"earth.jpg")
    return (
        <main style={{width: "100vw", height: "100vh"}}>
            <Canvas>
                <color attach="background" args={['#050505']} />
                <ambientLight intensity={3}/>
                <OrbitControls minDistance={101} maxDistance={200} rotateSpeed={0.4} zoomSpeed={0.5}/>
                <mesh castShadow position={[0, 0, 0]}>
                    <sphereGeometry args={[100, 128, 64]}/>
+                   <meshPhysicalMaterial map={earthMap}/>
                </mesh>
            </Canvas>
        </main>
    );
}

テクスチャをオブジェクトに貼り付けるのは簡単です。

  1. const texture = useLoader(TextureLoader,"image path")
    useLoaderの第一引数にTextureLoader,
    第二引数にテクスチャ画像のパスを渡します
  2. <meshPhysicalMaterial map={texture}/>
    マテリアルのmapに定義したテクスチャを渡します。

    一気に地球になりましたね。
    地球のテクスチャとして使用するのは普通に画像でいいです。

今回はNASAが公開している[1]画像を使用しました。
テクスチャを適用する際も特別なことは不要です。綺麗に貼り付けることができました。
もし、別の素材を使う場合は縮尺や歪みなど気を付ける必要がありそうです。(地図のメルカトル図法とか?)

画像はpublicディレクトリ直下に置いてあります。

つづく

今回はここまでです。
正直Three.jsのチュートリアルみたいな内容ですが。これだけでも動かしてると結構楽しいですね。
次は緯度経度を座標に変換します。

脚注
  1. コピーライトに関しては商用利用でなければ大丈夫です。 ↩︎

Discussion