NASAのEarth 3D Modelをthree.jsのGLTFLoader()を使って読み込んで表示させてみました。
わかったこと
three.jsのGLTFLoader()でちゃんと読み込んで表示できること。
Earth 3D Modelのサイズが1000あったので、使ったカメラPerspectiveCameraのfar (区間の終了距離)を大きくする必要があった。または、Earth 3D Modelのスケールで縮小する必要がった。
ライトを当てないと真っ黒になること(なので環境光源を明るめに当てました)。
扁平率が約1/298なので地球楕円体になっていたこと。
経度0度がthree.jsのz軸のマイナス方向だったこと。
作成したものは以下で確認できます。
作成
GLTFLoader()の使い方は、three.jsのドキュメントを参考にしました。
あとは、テキストを表示するのにthree.jsのドキュメントにあった DOM + CSS を使っています。
three.jsのシーンの作成はCreating a sceneを参考にしました。
全ソースコードはこうなりました。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Earth 3D Model - Earth_1_12756.glb</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body {
margin: 0;
overflow: hidden;
}
#info {
color: lightgrey;
position: absolute;
top: 10px;
width: 100%;
z-index: 100;
display: block;
}
</style>
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.164.1/build/three.module.js",
"three/addons/controls/OrbitControls": "https://unpkg.com/three@0.164.1/examples/jsm/controls/OrbitControls.js",
"three/addons/loaders/GLTFLoader": "https://unpkg.com/three@0.164.1/examples/jsm/loaders/GLTFLoader.js"
}
}
</script>
<div id="info">
Earth 3D Model - https://science.nasa.gov/resource/earth-3d-model/
<div id="automatically_generated">
</div>
</div>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader";
const renderer = new THREE.WebGLRenderer();
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
// XYZ軸を表示
const axesHelper = new THREE.AxesHelper(700);
scene.add(axesHelper);
// カメラ
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
1,
10000
);
camera.position.set(1000, 100, 100);
const controls = new OrbitControls(camera, renderer.domElement);
// 環境光源
const ambientLight = new THREE.AmbientLight(0xffffff, 5);
scene.add(ambientLight);
const automaticallyGenerated = document.getElementById('automatically_generated');
// GLTFLoader: https://threejs.org/docs/#examples/en/loaders/GLTFLoader
const loader = new GLTFLoader();
loader.load(
// Earth_1_12756.glb: Earth 3D Model https://science.nasa.gov/resource/earth-3d-model/ の読み込み
"Earth_1_12756.glb",
// リソースがロードされたときに呼び出される
function (gltf) {
scene.add(gltf.scene);
const boundingBox = new THREE.Box3().setFromObject(gltf.scene);
const boxSize = boundingBox.getSize(new THREE.Vector3());
automaticallyGenerated.innerText = `Size of Earth 3D Model: x=${boxSize.x}, y=${boxSize.y}, z=${boxSize.z}`;
},
// 読み込み中に呼び出される
function (xhr) {
automaticallyGenerated.innerText = Math.round((xhr.loaded / xhr.total) * 100) + "% loaded";
},
// 読み込みエラーが発生したときに呼び出される
function (error) {
automaticallyGenerated.innerText = error;
}
);
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
function onWindowResize() {
const width = window.innerWidth;
const height = window.innerHeight;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
onWindowResize();
window.addEventListener("resize", onWindowResize);
</script>
</body>
</html>
Earth with Clouds 3D Model を使うと雲つきの地球が表示できました。
最初は表示されなくて、原因がわからず悩みましたが、サイズの問題と分かってからは特に問題なく表示できました。