整个宇宙将为你闪烁 除了三体人前端也可以 哈哈
整个宇宙将为你闪烁,这句话出自《三体》,当时就被吸引住了,然后就想着把它实现出来。项目主要使用 three.js,设计灵感及贴图来源于 Solar System Scope 。
📺 视频展示: Bilibili 哔哩哔哩
🚀 项目源码: GitHub
📖 前置项
在开始之前希望你对 three.js 有一定的了解,这里推荐一个教程,Discover threejs, three.js 主创之一编写的适合入门的教程。
项目只用原生 js 并没有引入 Vue 或 React 等框架,因为我想让项目更纯粹些,也希望自己不要离开框架就不会写代码了。
📚 基础设施
- 创建场景
1 | // scene.js |
- 创建相机
1 | // camera.js |
- 渲染场景
1 | // renderer.js |
🌌 添加物体到场景中
完成上面的基本操作,我们就可以往场景中添加物体了。
🌖 银河系及行星
创建一个球体,并给球体的材质使用纹理贴图。别忘了添加到场景中。
1 | // milkyWay.js |
行星的创建与银河系类似,因为都是创建球体。
💫 行星的轨迹
这里主要使用了 CatmullRomCurve3 创建一条平滑的三维样条曲线。
1 | // orbit.js |
创建圆环还有更简单的方法,就是直接使用 EllipseCurve 创建一个曲线,再将其进行旋转,也就是修改 orbit 的 rotation。 但是最后在行星的运动环节,使用 getPointAt 获取不到准确的值,只能拿到旋转前的值。
1 | import { EllipseCurve, BufferGeometry, LineBasicMaterial, Line } from 'three' |
🌞 太阳的发光效果
使用 EffectComposer 实现,具体的例子可以参考 three.js 官方示例 Bloom,用于太阳的辉光;
three.js 官方示例 Outline,用于太阳的边缘。
1 | import { Vector2, ShaderMaterial } from 'three' |
美颜前 | 美颜后 |
---|---|
🔖 行星的标签
使用 canvas 创建一张图片,再赋值给 Sprite 的材质,这个方式是参考了网上的一个例子。
1 | import { Sprite, SpriteMaterial, TextureLoader } from 'three' |
除此以外还有另外一种实现的方式,可以参考 three.js 官方示例 Label。
1 | import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js' |
这样看起来更简单一些,但是,那个标签的层级会比较高,我的行星根本没有办法挡住它!
🪐 行星的运动
这里逻辑就是获取轨迹线 curve 的点,将其所在位置赋值给行星组 group,因为月亮比较特殊所以要单独设置,这样就完成了公转。那么自转就更容易了只需要改变 group 的 rotation 就好了。
其实我觉得月亮和地球之间的处理方式有待优化,但我已经尽力了。
1 | // sphere.js |
至此,就可以得到这样的场景。
✨ 星光闪闪
没有一个例子能逃过我的手掌心,three.js 官方示例 Points, 用于闪烁的星星。
1 | import { |
🌠 宇宙闪烁
这里是往场景中添加红色的雾,但是 fog 并没有继承 Object3D 的 visible 属性,所以修改 density 的值去实现忽明忽暗的效果。我真是个平平无奇的大聪明,哈哈。
1 | import { FogExp2 } from 'three' |
📃 结语
至此,你学废了吗?感兴趣的朋友可以看下 GitHub 上的源码。
📑 参考资料
Discover threejs, three.js 主创之一编写的适合入门的教程。
Bloom, three.js 官方示例, 用于太阳发光的效果。
Outline, three.js 官方示例,用于太阳的边缘。
Sprite, three.js 官方示例,用于星体的标签
Points, three.js 官方示例,用于闪烁的星星。