仓库地址
laddish/threejs-build-earth
https://gitee.com/laddish/threejs-build-earth
预览地址
https://static-c4ab0b87-5a60-4e43-9cfc-1979c6de3ecd.bspapp.com/
效果图
鼠标可以控制地球
地球, 云层和背景星系都会移动
左上角显示渲染的帧数
主要思路
没什么难点, 最难的估计就是地球的贴图和云层贴图 背景贴图///笑死
地球云层星系都是创建了一个球体 然后引入材质贴图
主要代码
threejs中的几个重要的部分
scene 场景
camera 相机
light 光线
renderer 渲染器
缺一不可
注释写的很清楚 每一步干啥写的都很清楚
import "./style.css";import * as THREE from "three";//引入轨道控制import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";import Stats from "three/examples/jsm/libs/stats.module";import * as dat from "dat.gui";const stats = Stats();document.body.appendChild(stats.dom)// Debugconst gui = new dat.GUI();// 加载材质const loader = new THREE.TextureLoader();//加载earth贴图 放置在static目录下const texture = loader.load("texture/earthmap1k.jpg");//加载肿块const bumpMap = loader.load("texture/earthbump.jpg");// 加载云朵材质const cloudMap = loader.load("texture/earthCloud.png");// 加载星星材质const starMap = loader.load("texture/galaxy.png");// Canvas 至少需要 场景 渲染器 和 照相机 缺一不可// canvas 元素 是渲染器的渲染范围const canvas = document.querySelector("canvas.webgl");// Scene 场景const scene = new THREE.Scene();// Objects 创建几何球体 半径范围 宽度 高度const geometry = new THREE.SphereBufferGeometry(0.7, 32, 32);// Materials 创建材料const material = new THREE.MeshPhongMaterial({roughness: 1, //粗糙度metalness: 0,// 也可以使用// map:THREE.ImageUtils.loadTexture(),map: texture,bumpMap,bumpScale: 1,});//设置材料的颜色// material.color = new THREE.Color(0x00ff00);// Mesh 创建网孔球体const sphere = new THREE.Mesh(geometry, material);//把球体添加到场景中scene.add(sphere);//创建云朵球体 更大点const cloudGeometry = new THREE.SphereBufferGeometry(0.75, 32, 32);// Materials 创建材料const cloudMaterial = new THREE.MeshPhongMaterial({map: cloudMap,transparent:true, //设置为透明});// Mesh 创建网孔球体const cloudMesh = new THREE.Mesh(cloudGeometry, cloudMaterial);//把球体添加到场景中scene.add(cloudMesh);//创建星星球体 更大点 可能超出视野const starGeometry = new THREE.SphereBufferGeometry(80, 64, 64);// Materials 创建基础材料 没有光线const starMaterial = new THREE.MeshBasicMaterial({map: starMap,transparent:true, //设置为透明side: THREE.BackSide});// Mesh 创建网孔球体const starMesh = new THREE.Mesh(starGeometry, starMaterial);//把球体添加到场景中scene.add(starMesh);// Lights 光线 需要光线才能看到//创建环境光const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);//创建点光源const pointLight = new THREE.PointLight(0xffffff, 1);// 点光源必须要设置放置位置pointLight.position.x = 2;pointLight.position.y = 3;pointLight.position.z = 4;//为场景添加光线scene.add(ambientLight);scene.add(pointLight);/*** Sizes*/const sizes = {width: window.innerWidth,height: window.innerHeight,};//监听window的resize事件//更新camera的长宽比//更新renderer的大小window.addEventListener("resize", () => {// Update sizessizes.width = window.innerWidth;sizes.height = window.innerHeight;// Update cameracamera.aspect = sizes.width / sizes.height;camera.updateProjectionMatrix();// Update rendererrenderer.setSize(sizes.width, sizes.height);renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));});/*** Camera 照相机 创建透视摄影* fov 你想要看到的视角有多大多宽 一般为60* aspect 这个场景的长宽比* near 0.1* far 1000*/// Base cameraconst camera = new THREE.PerspectiveCamera(75,sizes.width / sizes.height,0.1,100);// position 照相机的放置位置camera.position.x = 0;camera.position.y = 0;camera.position.z = 2;scene.add(camera);// Controls 创建轨道控制器 接收参数 为相机 和 canvas元素const controls = new OrbitControls(camera, canvas);controls.enableDamping = true;/*** Renderer 渲染器*/const renderer = new THREE.WebGLRenderer({canvas: canvas,antialias: true, //开启抗锯齿(antialiased)渲染});//设置渲染器的大小renderer.setSize(sizes.width, sizes.height);//设置渲染器的像素值renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));//渲染前自动清理renderer.autoClear = false;//设置清理颜色renderer.setClearColor(0x000000, 0);/*** Animate*/const clock = new THREE.Clock();const tick = () => {const elapsedTime = clock.getElapsedTime();// Update objects 旋转球体的y轴sphere.rotation.y = -0.11 * elapsedTime;cloudMesh.rotation.y = -0.061 * elapsedTime;starMesh.rotation.y = -0.18 * elapsedTime;cloudMesh.rotation.x = -0.061 * elapsedTime;starMesh.rotation.x = -0.18 * elapsedTime;cloudMesh.rotation.z = -0.051 * elapsedTime;starMesh.rotation.z = -0.18 * elapsedTime;// Update Orbital Controls 更新轨道控制器 可以使用鼠标控制controls.update();// Render 渲染要在最后才能渲染renderer.render(scene, camera);stats.update()// Call tick again on the next framewindow.requestAnimationFrame(tick);};tick();
克隆
yarn addyarn dev
