threejs创建地球
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
threejs创建地球
上个⽉底,在朋友圈看到⼀个号称“”的分享,点进⼊后发现这个h5还很别致,思考了⼀会,决定要不⾼仿⼀个?
到今天为⽌,⾼仿基本完成,
除了⼿机端的media控制没有去兼容,其他的基本都给仿了。
那为了让你觉得是⾼仿,最好使⽤chrome的⼿机调试模式进⾏访问。
微信打开将听不见声⾳看不到视频... (后⾯再有时间看是不是仿的再进⼀步)
之所以要仿它,因为觉得这个h5还挺酷,想看看⾃⼰需要花多长时间找到并实现它的技术路径。
需求分析
这个h5的主要玩法很简单:地球⾃转的时候会播放背景⾳乐(⽐如海浪声),为了找到这个声⾳是从哪个地球上哪个地⽅传来的,需要长按下⽅的按钮,这时地球会⾃动转动到⽬标地点,然后镜头拉近,穿过云层,最后你会看到和这段声⾳相关的视频内容;松开⼿之后,上⾯的过程会倒退回去,地球⼜开始⾃转,播放着下段神秘的背景⾳乐。
个⼈觉得这个设计还是很新颖的,不是说⽤了3D的效果,⽽是将⼀个看起来很复杂的动画(从宇宙拉近到地表的过程),使⽤最基础的3D效果和其他⼀些常规的动画⼿法去实现,并且能流畅的运⾏在⼿机浏览器上。
另外还有声⾳和视频的完美搭配,⽤户体验不错。
反复观察,理清页⾯功能:
1. 加载:加载进度百分⽐,饶椭圆轨道运⾏的⼩⾏星作为loading动画(这个动画我没有做)
2. 地球:3D球体,旋转⼊场动画,⾃转,漂移的云层,城市的坐标点,镜头的旋转与拉近,穿越云层动画
3. 星空背景:静态星空背景图,动态(闪烁的)星星,划过的流星
4. 隐藏的⾳频和视频:按内容(地理位置)划分的⾳频和视频内容
5. 其他:操作指引⽰意动画,地球上⽅会显⽰当前城市的经纬度,“了解更多”的结语页⾯等
寻找技术路径
打开chrome inspect⼀下。
⾸先是这个地球,得看看它是真3D还是假3D(因为很多3D效果是拿雪碧图做的,⽐如这⾥的),结果找到了:
<div class="ns-webgl-page">
<canvas width="750" height="1200" style="width: 375px; height: 600px;"></canvas>
</div>
并且在⽹站source⽂件中搜到了THREE,那就是threejs没跑了。
然后是那个穿越云层的效果,猜测可能是GIF,可能是SpriteSheet Animation,也有可能是⼀段视频。
但是考虑到这个穿越的动画可以正反双⽅播放,那么就很可能是是SpriteSheet Animation了,否则GIF或者视频⽂件需要两个动画⽅向各准备⼀份。
这个从chrome debug⼯具的network下找到了证据—— 页⾯下载了⼀系列名为kf_cloud_0000X.jpg的图⽚⽂件。
顺⼿就把它们down下来,备⽤。
再就是背景⾳乐和隐藏视频的问题,同样在network下,找到了两个⽂件,⼀个mp3⼀个mp4,每个⽂件都包含了所有⽚段,就像是media的雪碧图,只在需要的时候控制播放对应⽚段⽽已。
其他的内容都没什么问题,CSS动画或者CANVAS都好做。
那么到此,技术路径都清楚了,准备开始写代码。
难点突破
对于我⽽⾔,⽤threejs绘制地球可能会是难点,threejs没有⽤过,⽽且印象中对3D的东西,⼀直⽐较敬畏。
如果3D的地球弄不出来,这个项⽬其他的都做完了,在浩瀚的宇宙中是怎么也找不到“声⾳来⾃何⽅”了。
OK,来看threejs怎么能弄出个地球来。
(这个阶段并没有开始项⽬代码,⽽是尽量的在⼀个临时⽂件中进⾏涂鸦,快速随意的达到绘制出地球的⽬的就⾏了)
官⽹
对于新的技术,⾸先得看。
这⾥并不是来全⾯学习threejs的,⽽是抱着很强的⽬的性去实现特定功能,因此直接去⽰例中找,是否有类似实现可以借鉴。
在官⽹⾸页中,通过缩略图,找到了下⾯三个关于地球的例⼦。
可惜,貌似这⾥的例⼦都是⼀些产品应⽤,代码都是压缩过的。
于是开始去寻找官⽅⽰例,最后在⾥找到了,最棒的是在github上有。
⽰例代码
clone下threejs的项⽬代码,找到上⾯的⽰例⽂件。
⽰例代码不到200⾏,阅读之后发现其实threejs和之前接触过的⼀些2D的游戏引擎(createjs,pixijs)等⽐较类似,都需要有场景(scene),要有渲染循环(render loop),在scene上添加对象(Mesh)或者是group;⽽Mesh由形状(Geometry)和材质(Material)组成,Material则⼜是由图⽚创建的纹理(Texture)⽽来。
不同的是,这⾥有相机(Camera),有光线(Light),还有⼀些⼀直都不明⽩的距离单位问题。
稍微改动⼀下⽰例代码,就能创建出来了earth。
但是从使⽤的资源来看,只有⼀个地表纹理贴图(earth4.jpg),⽽xplan中还有3个关于earth的图⽚⽂件:
不确定bump和spec是什么,我的思路是先在官⽅⽂档中找这些关键词,如果找不到,就加上threejs⼀起去做google。
官⽹上找到了bump相关的东西,但帮助最⼤的是google出来的⼀篇详细的如何使⽤threejs创建earth的。
(如果这个教程早点冒出来,也省了前⾯改⽰例代码的时间了。
主要也源于对threejs不熟悉,没有想到哪些⽰例可能已经有很多教程了)
换上了earth4.jpg贴图之后:
earth_bump
了解到bumpmap:
Bump mapping is a technique to simulate bumps and wrinkles on the surface of an object. The result is an apparently bumpy surface rather than
a smooth surface although the surface of the underlying object is not actually changed. I'm sorry, you can't tilt the camera to see 3D mountains
with this technique. You can adjust the bump effect (how much the map affects lighting) with the bumpScaleparameter
threejs中bumpmap是调节对光线的感知,来使⼈能明显感觉到不光滑的表⾯,⽽并没有在mesh中添加起伏,即没有真的改变形状。
官⽅bumpmap⽰例效果图如下:
其实这⾥的earth_bump.jpg就是⼀个,在threejs中称作bumpmap,在其他⼀些地⽅也有被叫做heightmap。
即⽤灰度图表达⾼程,越⿊表⽰⾼程越低,越亮表⽰⾼程越⾼。
GIS专业中常⽤,unity3D中创建地形也会⽤到这个。
添加了earth_bump之后:
earth_spec
了解到了earth_spec.jpg是specular map,⽤来调节镜⾯反射的,这⾥主要是调节海洋对光线的反射,增加真实性。
添加了earth_spec之后:
漂移的云层
云层的添加,前⾯的教程⾥已经很详细了,其实就是⼀个同⼼,半径⼤⼀点的球体⽽已。
添加了云层之后:
浮动的标签
xplan中地球表⾯有城市标签,会随着地球的⾃转⽽移动,同时⼜保持了⽔平的⽅向。
google关键词:threejs floating label。
于是找到:
找到⽅向就好办,稍微参考⼀下官⽅API⽂档和找到的⽰例代码,能够很容易的在earth上添加上浮动标签。
⼩结
到这⾥,3D地球的绘制基本差不多了。
虽然threejs是新东西,但是绝⼤部分功能都容易找到⽅向,并且改动⼀下⽰例代码都够快速的实现我们想要的效果,所这个过程并不难。
重点是如何在⼀个未知的领域内找到想要的东西,并且快速的为⾃⼰所⽤。
但过程中我碰到⼀个性能问题,耽误了很久。
xplan的页⾯在chrome的PC和⼿机模式都有近60的FPS,但是我创建的earth在PC有60,但是在⼿机模式却不到30!最后逐⼀调试代码,修改参数,花了好久才找到原因:
renderer.setPixelRatio(window.devicePixelRatio)
threejs的⽰例代码中都有这么⼀⾏,就是这⼀⾏导致了我的代码⽐xplan的代码在⼿机上绘制的像素点翻倍,从⽽导致了性能成倍的下降。
另外,前⾯也提到,我对于3D框架中的距离单位和坐标问题,很模糊。
于是这⾥,关于earth的⼤⼩,camera朝向,每个城市标签的三维坐标和其他关与三维坐标的问题,我都硬抄了xplan的参数(幸好他们的代码没有压缩...)。
还有⼀个要承认的,就是地球后⾯的淡蓝⾊光晕效果,貌似⽤了⼀些⾼级的渲染技
术,我也就硬搬了xplan这部分代码。