想做一個主頁,頁面上有一個地球和雲層的3D效果。想了下這個使用Three.js還是 蠻簡單 的。首先給一個SphereGeometry加上地球紋理,再給另一個SphereGeometry加上透明的雲層紋理,套在一起,加上動畫就好了
效果預覽(使用高清點的紋理圖片效果應該會好很多):
首先定義場景等基本要素:
const WIDTH = document.body.clientWidth;
const HEIGHT = document.body.clientHeight;
//定義 scene, camera, render
let scene = new THREE.Scene();
//透視投影
let camera = new THREE.PerspectiveCamera(75, WIDTH/HEIGHT, 0.1, 2000);
//正射投影
//camera = new THREE.OrthographicCamera( WIDTH / -2, WIDTH / 2, HEIGHT / 2, HEIGHT / -2, 1, 2000 );
camera.position.z = 150;
//antialias 抗鋸齒
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(WIDTH, HEIGHT);
document.querySelector('#container').appendChild(renderer.domElement);
導入紋理(這裏返回的是Promise,便於使用async函數):
/**
* 導入紋理
* @param path
* @returns {Promise}
*/
function loadTexture(path){
return new Promise((resolve, reject)=>{
let loader = new THREE.TextureLoader();
loader.load(path, texture => {
resolve(texture);
} , ()=>{} , ()=>{reject('fail')});
});
}
發現現在的Three提供了THREE.Group對象,可以把多個Mesh進行組合,這樣可以同時控制Mesh的位置:
//地球還包含雲層
let earth = new THREE.Group();
加上地球和雲層的紋理,由於雲層紋理是一張透明的PNG圖片,需要設置Mesh的transparent爲true:
//地球
earth.position.z = 0;
let earthTexture = await loadTexture('img/earth.jpg');
let earthGeometry = new THREE.SphereGeometry( R_EARTH, 50, 50 );
let earthMaterial = new THREE.MeshBasicMaterial( { map: earthTexture, overdraw: 0.5 } );
let earthMesh = new THREE.Mesh( earthGeometry, earthMaterial );
earth.add( earthMesh );
//地球的雲層
let cloudTexture = await loadTexture('img/clouds.png');
let cloudGeometry = new THREE.SphereGeometry( R_EARTH+5, 50, 50 );
let cloudMaterial = new THREE.MeshBasicMaterial( { map: cloudTexture, overdraw: 0.5, transparent: true} );
let cloudMesh = new THREE.Mesh( cloudGeometry, cloudMaterial );
earth.add( cloudMesh );
加上旋轉動畫:
function animateRunner(){
this.delta = 0;
this.run = function(){
earth.rotation.y -= 0.002;
requestAnimationFrame( this.run.bind(this) );
renderer.render( scene, camera );
}
}
動態效果(渣渣效果-_-||):