3D Earth Display (Three.js [r145])
With three.js, you can easily display a 3D Earth on the web by rendering a sphere for the Earth and another for the clouds, then simply rotating them.
The images used are provided free of charge by NASA.
The Earth image data is distributed here:
https://visibleearth.nasa.gov/images/57752/blue-marble-land-surface-shallow-water-and-shaded-topography
The cloud image data is distributed here, processed to be transparent (alpha channel added):
https://visibleearth.nasa.gov/images/57747/blue-marble-clouds
Rotate with left mouse drag, move the camera with right mouse drag.
On touch devices: swipe to rotate, move the camera by dragging with two fingers.
Source Code
<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:front, counterclockwise
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=[];
// Create scene
scene = new THREE.Scene();
// Create and set camera
var width = document.getElementById("can").getAttribute("width");
var height = document.getElementById("can").getAttribute("height");
// field of view, aspect ratio, near, far
camera = new THREE.PerspectiveCamera( 60, width/height, 0.01, 100 );
camera.position.set(0,0,3);
camera.lookAt(new THREE.Vector3(0, 0, 0));
// Place renderer on DOM
renderer = new THREE.WebGLRenderer({'canvas':document.getElementById('can') , antialias: true});// enable antialiasing
renderer.setSize( width, height );
renderer.shadowMap.enabled = true;// enable shadows
renderer.shadowMapSoft = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
document.getElementById('can').style.width="100%";
document.getElementById('can').style.height="auto";
// ■ Set background color
//renderer.setClearColor(0x88ccff, 1);
renderer.setClearColor(0x000000, 1);
// Light ------------------------------------------------
// Ambient light (light applied to all objects from all directions). Without this, unlit areas are completely black.
var AmbientLight=new THREE.AmbientLight(0xffffff,0.3);
scene.add( AmbientLight );
// Load images
images=await Promise.all(imageFiles.map(loadImage));
// Load textures
for(let i=0;i<imageFiles.length;i++){
texture[i]=new THREE.TextureLoader().load(imageFiles[i]);
material[i]=new THREE.MeshLambertMaterial({
color: 0xffffff, // color
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]);
// Spotlight color, intensity, distance, angle, penumbra[0-1], decay[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;// enable shadows
spot.shadow.mapSize.width = 4096; // high quality shadows
spot.shadow.mapSize.height = 4096; // high quality shadows
spot.shadow.radius=8;
scene.add(spot);
scene.add(spot.target);
// Create orbit controls (camera moves with mouse drag, wheel, etc.)
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>
