トップへ(mam-mam.net/)

Display a Realistic 3D Earth in Your Browser! [Beautifully Recreated with Three.js and NASA Images]

Japanese

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, zoom in/out with the wheel.
On touch devices: swipe to rotate, move the camera by dragging with two fingers, pinch in/out to zoom.

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>

Back to the list of 3D content with JavaScript