1.最终效果展示
星球面向太阳部分接受光照,背面显示为黑色
图1 整体观感
图2 地球云层/阴影
图3 土星环(渣效果)
源代码已上传github:GitHub - Youzica/SolarSystem
2.材料收集开发准备
材料收集
主要收集各种星系的贴图:Solar Textures | Solar System Scope贴图资源来自该网站;
开发准备
主要环境是vue3+three, node版本为16.15.0,npm版本为8.5.5;
新建一个项目后install three即可;
"dependencies": {
"core-js": "^3.8.3",
"three": "^0.156.1",
"three-css2drender": "^1.0.0",
"three-obj-mtl-loader": "^1.0.3",
"three-orbit-controls": "^82.1.0",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vue3-print-nb": "^0.1.4",
"vuex": "^4.0.0"
},
3.自转完成方法
对于3D场景,three以(x,y,z坐标表示)其存在的位置,x轴相当于画的一条横线,y轴相当于画的一条竖线,z轴相当于电脑屏幕的一条法线(垂直电脑平面);因此,完成球体的自转就是球体绕着本身的y轴进行旋转。
// 自转
this.sunMesh.rotateY(0.001);
this.earthMesh.rotateY(0.01)
this.xiaoxin.rotateY(0.01)
this.mercuryMesh.rotateY(0.01)
this.moonMesh.rotateY(0.005);
this.marsMesh.rotateY(0.003)
this.venuMesh.rotateY(0.004)
4.公转完成方法
公转则是绕着x轴和z轴做圆周运动;
// 公转
this.earthMesh.position.x = 200 * Math.cos(Date.now() * 0.0001);
this.earthMesh.position.z = 200 * Math.sin(Date.now() * 0.0001);
//200 旋转的坐标位置
//0.0001 旋转的速度 设置cos\sin可以设置旋转的方向
5.地球云层完成方法
地球云层实际上是一个圆包含了另一个圆,外边的圆设置透明度将内层的圆显示出来;
//定义地球和云层的球体
var geometryEarth = new THREE.SphereGeometry(15, 32, 32);
var geometryEarthCloud = new THREE.SphereGeometry(15.8,32,32);//地球云层
//地球云层的宽度要比地球的宽度宽一些 15.8>15
载入纹理;
//载入纹理
var textureEarth = new THREE.TextureLoader().load(
require("../assets/earth.jpg")
);
var textureEarthCloud = new THREE.TextureLoader().load(
require("../assets/earth_clouds.jpg")
);
设置地球和云层的材质 光照不影响Basic材质,这里选择使用Phong材质 ;
//设置地球和云层的材质 光照不影响Basic材质,这里选择使用Phong材质
var materialEarth = new THREE.MeshPhongMaterial({
map: textureEarth,
shininess:150,
});
var materialEarthCloud = new THREE.MeshPhongMaterial({
map: textureEarthCloud,
opacity:0.5, //设置透明度 0.5 0~1
transparent:true //开启透明
});
mesh对象叠加,这里可以将云层设置为scene的子元素,也可以加到earthMesh中,两种方法都可以;设置到scene中就表示cloud和earth层没有关系,需要再设置云层的公转与自转与地球相同
this.earthMesh.add(this.earthCloud);
//mesh对象叠加,这里可以将云层设置为scene的子元素,也可以加到earthMesh中,两种方法都可以
//设置到scene中就表示cloud和earth层没有关系,需要再设置云层的公转与自转与地球相同
6.月球完成方法
月球的完成方法和地球云层差不多,这里moon公转的距离以及速度是相对与地球中心的距离;
//几何体
var geometrymoon = new THREE.SphereGeometry(2, 32, 32);
//纹理
var texturemoon = new THREE.TextureLoader().load(
require("../assets/moon.jpg")
);
//材质
var materialmoon = new THREE.MeshPhongMaterial({
map: texturemoon,
});
//合成Mesh对象
this.moonMesh = new THREE.Mesh(geometrymoon, materialmoon);
//地球Mesh加入moon moon是earth的子元素
this.earthMesh.add(this.moonMesh);
//月球绕着地球的距离和速度
this.moonMesh.position.x = 20 * Math.cos(Date.now() * 0.001);
this.moonMesh.position.z = 20 * Math.sin(Date.now() * 0.001);
7.土星环完成方法
环状几何体同其他方法的差距就是几何体的使用方法不同。
var geometrySaturn = new THREE.SphereGeometry(17, 32, 32);
//17 土星的大小
var geometrySaturnRing = new THREE.RingGeometry(18,20, 32);
//18-20环的大小
这里使用的是土星环加入到scene中,因此需要在公转中加入土星环的旋转速度需要和土星相同;
this.scene.add(this.saturn_ring)
//土星
this.saturn.position.x = 370 * Math.cos(Date.now() * 0.00025);
this.saturn.position.z = 370 * Math.sin(Date.now() * 0.00025);
//土星环
this.saturn_ring.position.x = 370 * Math.cos(Date.now() * 0.00025);
this.saturn_ring.position.z = 370 * Math.sin(Date.now() * 0.00025);
8.太阳光照阴影完成方法
需要了解一下哪些材质可以受到光的影响,以及具体有什么光;
这里可以参考:three.js manual
太阳光照射这里使用的光源是点光源,点光源位置设置在原点,球体的材质设置为MeshPhongMaterial(受光照影响);
// 创建点光源
var point = new THREE.PointLight(0xffffff,100000); 光照颜色,强度
point.position.set(0,0,0);
this.point = point;
console.log(this.point);
this.scene.add(this.point);
大概思路就是这样,具体实现的代码也有记录,欢迎讨论学习(我也就看了一周左右,可能会有更好的方法与效果不了解)。