1
/
5

Three.jsで簡単な動き地球を作ってみた

さて、今回はThree.jsを使って動くページを作成してみたいと思います。

目次

  • 基本的なテンプレートを設定

  • 地球のメッシュを作成

  • SphereGeometryを作成し、カメラの位置とレンダリングを設定

  • 地球のマテリアルを作成

  • 画面が見えるように光も追加

  • 地球のテクスチャを作成

  • 雲層を追加

  • 大気圏を追加

  • 星空の背景を追加

  • おわりに

基本的なテンプレートを設定

// HTML-Three.js ライブラリの読み込み

src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"

// CSS-画面全体のレイアウト設定
body {
margin: 0; overflow: hidden;
}
canvas {
display: block;
}
#text-overlay {
position: absolute;
top: 50%;
left: 20%;
transform: translateY(-50%);
color: white;
font-weight: bold;
font-family: Arial, sans-serif;
font-size: 36px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
}
// Three.jsのセットアップ

// シーン、カメラ、レンダラーの作成
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);

// ウィンドウのリサイズ処理
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}

地球のメッシュを作成

SphereGeometryを作成し、カメラの位置とレンダリングを設定

// 地球のジオメトリを作成

const earthGeometry = new THREE.SphereGeometry(1, 64, 64);

// 地球のメッシュを作成
const earth = new THREE.Mesh(earthGeometry);
scene.add(earth);

// カメラの位置を設定
camera.position.set(1, 0, 4); // カメラを少し遠ざける

// レンダリング
renderer.render(scene, camera);

地球のマテリアルを作成

// 地球のジオメトリを作成

const earthGeometry = new THREE.SphereGeometry(1, 64, 64);

// 地球のマテリアルを作成
const earthMaterial = new THREE.MeshPhongMaterial({
specular: new THREE.Color('grey'),
});

// 地球のメッシュを作成
const earth = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earth);

画面が見えるように光も追加

// 環境光を追加

const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);

// 平行光源を追加して太陽光をシミュレート
const sunLight = new THREE.DirectionalLight(0xffffff, 1);
sunLight.position.set(5, 3, 5);
scene.add(sunLight);

地球のテクスチャを作成

// 地球のジオメトリを作成

const earthGeometry = new THREE.SphereGeometry(1, 64, 64);

// 地球のテクスチャを読み込む
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg');
const earthNormalMap = textureLoader.load('https://threejs.org/examples/textures/planets/earth_normal_2048.jpg');
const earthSpecularMap = textureLoader.load('https://threejs.org/examples/textures/planets/earth_specular_2048.jpg');

// 地球のマテリアルを作成
const earthMaterial = new THREE.MeshPhongMaterial({
map: earthTexture,
normalMap: earthNormalMap,
specularMap: earthSpecularMap,
specular: new THREE.Color('grey'),
shininess: 10
});

// ....

// アニメーションループ(シーンを継続的に更新し再描画するために、アニメーションループが必要です。)
function animate() {
requestAnimationFrame(animate);
// 地球をゆっくり回転させる
earth.rotation.y += 0.002;
renderer.render(scene, camera);
}
animate();

これでもう完成ですが、見た目をさらによくするために、雲層と大気圏も作りましょう。

雲層を追加

//...


// 雲層を作成
const cloudsGeometry = new THREE.SphereGeometry(1.01, 64, 64);
const cloudsTexture = textureLoader.load('https://threejs.org/examples/textures/planets/earth_clouds_1024.png');
const cloudsMaterial = new THREE.MeshPhongMaterial({
map: cloudsTexture,
transparent: true,
opacity: 0.4 // 雲の不透明度を下げる
});
const clouds = new THREE.Mesh(cloudsGeometry, cloudsMaterial);
earth.add(clouds);

// カメラの位置を少し調整し、センターに移動
camera.position.set(0, 0, 5);

//...

// アニメーションループ
function animate() {
requestAnimationFrame(animate);
// 地球をゆっくり回転させる
earth.rotation.y += 0.002;
clouds.rotation.y += 0.0023;
renderer.render(scene, camera);
}

大気圏を追加

// 大気圏の光輪効果を作成

const atmosphereGeometry = new THREE.SphereGeometry(1.1, 64, 64);
const atmosphereMaterial = new THREE.ShaderMaterial({
vertexShader: `
varying vec3 vNormal;
void main() {
vNormal = normalize(normalMatrix * normal);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
varying vec3 vNormal;
void main() {
float intensity = pow(0.7 - dot(vNormal, vec3(0.0, 0.0, 1.0)), 2.0);
gl_FragColor = vec4(0.3, 0.6, 1.0, 1.0) * intensity;
}
`,
blending: THREE.AdditiveBlending,
side: THREE.BackSide
});
const atmosphere = new THREE.Mesh(atmosphereGeometry, atmosphereMaterial);
scene.add(atmosphere);

最後に背景を追加したら完成です!

星空の背景を追加

// 星空の背景を追加

const starsGeometry = new THREE.BufferGeometry();
const starsMaterial = new THREE.PointsMaterial({color: 0xffffff, size: 0.02});
const starsVertices = [];
for (let i = 0; i < 10000; i++) {
const x = THREE.MathUtils.randFloatSpread(2000);
const y = THREE.MathUtils.randFloatSpread(2000);
const z = THREE.MathUtils.randFloatSpread(2000);
starsVertices.push(x, y, z);
}
starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starsVertices, 3));
const starField = new THREE.Points(starsGeometry, starsMaterial);
scene.add(starField);

おわりに

いかがでしょうか?基本的な考え方は、まずシーン、カメラ、レンダラーを設定し、カメラの位置を調整します。そのあとでSphereGeometryを三つ作成し、それぞれに異なるマテリアルを与えて、同じ場所に配置します。

最後まで読んでいただき、ありがとうございます。これからも頑張ります!


記事を読んで興味を持った方はぜひコチラから↓

フロントエンドエンジニア
チームと共にプロジェクトを成功へ導くテクニカルディレクターを募集!!
ロジカルスタジオは、テクノロジーとデザインの視点からクライアントの課題解決をめざす、大阪のクリエイティブプロダクションです。 クライアントの期待を超えて「もっと良くなる、を見つける」のが私たちのスタイル。企画・提案からデザイン制作・システム構築、運用、改善提案をワンストップで行えるのが一番の強みです。近年ではその実績と品質が評価され、案件も急増しています。 代表の古川が掲げる企業理念は「絆を大切に、周りの人を豊かにし、社会に貢献する」。 私たちはこのミッションを推進するため、「新しい技術へのチャレンジ精神」を軸に、「切磋琢磨する仲間」と「働きやすい職場環境」を整え、「成長と可能性を大切にする風土」を育ててきました。 2019年9月に増床し、外部向けのセミナーにも活用できるカンファレンスルームを拡充。スタッフによる公式ブログや、マスコットキャラクター「ロージー&カール」によるTwitterなど、情報発信も強化しています。 可能性の芽をすくい上げられるこの場所を、より大きくしていきたい。 私たちと一緒に、このビジョンを実現しませんか。
株式会社ロジカルスタジオ


Invitation from 株式会社ロジカルスタジオ
If this story triggered your interest, have a chat with the team?
株式会社ロジカルスタジオ's job postings
11 Likes
11 Likes

Weekly ranking

Show other rankings
Like KOO's Story
Let KOO's company know you're interested in their content