创作背景
马上又是一年中秋佳节到来之际,中秋佳节自古以来就是团圆,思乡的节日,佳节当晚一边赏着月色,一边品尝着美味的月饼,和亲人好友诉说着想念之情 ,悠闲惬意之情油然而生。
古人有诗云:”明月几时有,把酒问青天,不知天上宫阙,今夕是何年?“ 这是古人对月亮和太空的理解,那么当现代的我们抬头望向星空,望向月亮的时候,你的太空遐想是什么呢?正好博主最近也在研究3维方面技术栈,来吧,这篇文章会从0和你一起用three.js 来实现:你心目中的地球和月球,并且在
漫天的繁星中画出行星运转轨迹,并保留有一个小彩蛋哦
功能分解
- 3d地球
- 3d月球
- 3d小火箭
- 地球自转轨迹 和 月球、小火箭旋转的行星轨道
- 彩蛋
创建3d地球
如何实现一个3d地球呢
第一步:我们首先需要创造一个三维的空间场景
/*
* 实例化场景
*/
scene = new THREE.Scene();
three.js封装好了三维场景实例化的方法,通过new THREE.Scene(),我们就可以创建了一个三维场景
第二步:我们向三维场景里面加一个摄像机,方便我们查看三维场景中的内容
/**
* 场景添加相机
*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); //透视相机
camera.position.z = 15;
scene.add( camera )
相机概念示意图
第三步:创建我们的地球啦,先使用new THREE.SphereGeometry(EARTH_RADIUS, 32, 32)创建一个球体,再给咱们的球体贴上地球地图的材质,这里博主已经收集了,一并放在工程目录上,阅读完本文后,可以下载使用,最后再使用new THREE.Mesh(earthGeometry, earthMaterial1)方法,这样一个地球就创建成功啦
材质图:
/**
* 场景中添加地球
*/
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS, 32, 32); //球体创建方法
const earthMaterial1 = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load('./asset/img/textures/planets/earth_atmos_2048.jpg'), // 添加纹理
shininess: 5,
})
earth = new THREE.Mesh(earthGeometry, earthMaterial1) //网格模型对象Mesh
earth.position.set(0, 0, 0)
earth.castShadow = true; // 光源有阴影
earth.receiveShadow = true
scene.add(earth); //创建地球
第四步:执行threejs的渲染函数requestAnimationFrame() 这个频率为每秒60帧,让我们的场景实时动起来
创建3d月球
创建3d月球的方法步骤和3d地球类似,这里就不重复概述啦,将成功创建后的3d月球场景p给大家看一下
创建3d小火箭
因为3d火箭的模型结构较为复杂,这里我们直接使用three.js官方提供的模型文件来导入场景,
方法如下:
/**
* 场景中添加飞船 (飞船造型太复杂,代码是画不出来滴 直接导入模型)
*
*/
const loader = new LWOLoader();
loader.load('asset/model/lwo/Objects/LWO3/Demo.lwo', function(object) {
rocket = object.meshes[2]; //这个模型有三部分 火箭是第三个
rocket.position.set(0, 0, 0);
rocket.scale.set(0.5, 0.5, 0.5);
// rocket.rotateZ(MathUtils.degToRad(-90))
scene.add(rocket);
});
这三个场景,博主已经分布写成三个demo,大家后续clone下来自行查看
设计地球自转轨迹和月球、小火箭旋转的行星轨道
刚刚我们都已经实现了模型的创建和加载,这里我们把这个三个模型加在一个场景里面,再给每个模型设计一下自己的运行轨迹,这样就可以完成我们的地球-飞行器-月亮的太空运行轨迹遐想啦
1.地球的自转轨迹
通过学习three.js的官方文档可知,three.js提供了rotateOnAxis 方法,这个方法可以在局部空间中绕着该物体的轴来旋转一个物体 ,使用方法如下,传入两个参数( axis : Vector3, angle : Float )坐标轴和弧度,我们可将地球设置为围绕Y轴选择,转的角度为圆周率的等分点即可
earth.rotateOnAxis(new Vector3(0,1,0),3.14)
2.月球的公转轨迹
这个就比较复杂,月球需要围绕着地球来旋转,这个运行轨迹在空间中是个圆,在官方文档学习示例中,我们可以看到月球的运动轨迹就是通过修改月球在三维坐标系中的x和z值来实现的,也就是这行关键代码:
moon.position.set(Math.sin(elapsed) * 5, 0, Math.cos(elapsed) * 5);
x轴坐标:
Math.sin(elapsed)*5
y轴坐标:
Math.cos(elapsed)*5
球的运动轨迹,是围绕y轴,在xoz形成的平面内画圆。
通过以上观察,在运动轨迹上,任一点的坐标x,z坐标满足一下规律:
也就是三角函数的正弦余弦平方和为1,即半径为1。
3.小火箭的公转轨迹
火箭的公转轨迹也设计的和月球相同,后续有想法的小伙伴,可以写写更为复杂的数学公式,实现更多不同的运动轨迹。
最终效果展现
最后我们将全部元素组装到一个场景里面,就可以实现如下的效果,怎么样,还不错吧
彩蛋
最后本项目,开源在gitcode上面,里面包含了项目的全部代码和模型,贴图素材,需要学习的朋友可以去自行下载学习:
国服第二切图仔 / Earth Moon Rockey Fly · GitCode
在此链接gitcode前 加上 ide ,即可使用网页版的vscode查看本项目:
Cloud IDE
关于火箭的运行轨迹其实可以设计的更加合理一点(现在也绕地球飞行),这里也保留一点遗憾,希望各位大佬,设计出更合理的运行轨迹(在绕地飞行的同时还能,从地球出发,飞往月球)来一起完善这个项目
最后提前祝大家中秋节快乐,也希望通过这个小项目,可以激发你对软件开发的兴趣,有喜欢本项目的朋友,希望可以给个一键三连鼓励一下博主,也欢迎评论区留言互动~~
版权归原作者 国服第二切图仔 所有, 如有侵权,请联系我们删除。