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