地球の3D表示(Three.js[r145])
three.jsを使うと地球の球体と雲の球体を表示して回転するだけなので、Webで3Dの地球を簡単に表示できます。
画像はNASAで無償提供しているものを利用しました。
地球の画像データはこちらで配布されています。
https://visibleearth.nasa.gov/images/57752/blue-marble-land-surface-shallow-water-and-shaded-topography
雲の画像データはこちらで配布されているものを透明に加工(アルファチャネルの追加)して使いました。
https://visibleearth.nasa.gov/images/57747/blue-marble-clouds
マウス左ドラッグで回転、右ドラッグでカメラの移動できます。
スワイプで回転、画面に2本指を触れてなぞるとカメラの移動です。
ソースコード
<canvas id="can" style="width: 100%; height: auto; max-width:calc(100vw - 32px);max-height:calc(100vw - 32px);cursor:pointer;" width="1000" height="600"></canvas>
<script>
//X:→ Y:↑ Z:手前、反時計回り
var camera,spot;
var imageFiles=["./imgs/earth.jpg","./imgs/cloud.png"];
var mesh=[];
async function loadImage(src){
return new Promise(function(resolve,reject){
let img=new Image();
img.onload=function(){resolve(img);}
img.onerror=function(e){reject(e);}
img.src=src;
});
}
window.addEventListener( 'DOMContentLoaded', async function(){
var images=[];
var material=[];
var texture=[];
//シーンを作成
scene = new THREE.Scene();
//カメラを作って設定
var width = document.getElementById("can").getAttribute("width");
var height = document.getElementById("can").getAttribute("height");
// 視野角,アスペクト比,近距離,遠距離
camera = new THREE.PerspectiveCamera( 60, width/height, 0.01, 100 );
camera.position.set(0,0,3);
camera.lookAt(new THREE.Vector3(0, 0, 0));
//レンダラーをDOM上に設置する
renderer = new THREE.WebGLRenderer({'canvas':document.getElementById('can') , antialias: true});//アンチエイリアスをtureにする
renderer.setSize( width, height );
renderer.shadowMap.enabled = true;//影可能
renderer.shadowMapSoft = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
document.getElementById('can').style.width="100%";
document.getElementById('can').style.height="auto";
//■背景色の設定
//renderer.setClearColor(0x88ccff, 1);
renderer.setClearColor(0x000000, 1);
//光源------------------------------------------------
//環境光(すべての物体にすべての方向から与える光)これがないと光の当たらない部分は真っ黒になる
var AmbientLight=new THREE.AmbientLight(0xffffff,0.3);
scene.add( AmbientLight );
//画像のロード
images=await Promise.all(imageFiles.map(loadImage));
//テクスチャのロード
for(let i=0;i<imageFiles.length;i++){
texture[i]=new THREE.TextureLoader().load(imageFiles[i]);
material[i]=new THREE.MeshLambertMaterial({
color: 0xffffff, //色
map:texture[i],
side:THREE.DoubleSide, //THREE.DoubleSide, THREE.FrontSide, THREE.BackSide
transparent:true,
opacity:1.0,
});
}
material[1].opacity=1;
let sphereGeometry=new THREE.SphereGeometry(1,64,32,0,Math.PI*2);
mesh[0]=new THREE.Mesh(sphereGeometry,material[0]);
mesh[0].rotation.z=23.43/180*Math.PI;
mesh[0].rotation.y=Math.PI/2;
scene.add(mesh[0]);
mesh[1]=new THREE.Mesh(sphereGeometry,material[1]);
mesh[1].scale.set(1.01,1.01,1.01);
scene.add(mesh[1]);
//スポットライト 色, 強さ,距離(distance),角度(angle),半影[0-1],減衰[1,1.5]
spot=new THREE.SpotLight(0xffffff, 4, 20,Math.PI*0.5, 0.8, 1.2);
spot.position.set(0,4,8);
spot.target.position.set(0,0,0);
spot.castShadow=true;//影を表示可能に
spot.shadow.mapSize.width = 4096; //影をきれいにする
spot.shadow.mapSize.height = 4096; //影をきれいにする
spot.shadow.radius=8;
scene.add(spot);
scene.add(spot.target);
//オービットコントロールの作成(マウスの左右ボタンドラッグ、ホイール等でカメラが動くようになる)
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0,0,0);
controls.update();
renderLoop();
});
function renderLoop () {
mesh[0].rotation.y+=Math.PI/360/4;
mesh[1].rotation.y+=Math.PI/360/4*1.2;
//mesh[1].rotation.x+=Math.PI/360/4;
renderer.render( scene, camera );
setTimeout(renderLoop,33);
}
</script>
