three完成SolarSystem,自转、公转、地球云层、月球、土星环、太阳光照阴影(附源码以及关键部分完成代码讲解)

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

8. 光源对物体表面影响 | Three.js中文网

太阳光照射这里使用的光源是点光源,点光源位置设置在原点,球体的材质设置为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);

大概思路就是这样,具体实现的代码也有记录,欢迎讨论学习(我也就看了一周左右,可能会有更好的方法与效果不了解)。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值