转载

UC星座占卜H5(技术篇)

从接触 WebGL,到入门 three.js,到各种修修改改,到活动上线,前后耗费了14个工作日。这里简单说一点技术沾边的东西,附上星座测试二维码,建议UC浏览器或微信查看

UC星座占卜H5(技术篇)

技术上的尝试

WebGL 是什么

WebGL 是一种3D绘图标准,允许把 JavaScript 和 OpenGL ES 2.0 结合在一起,为 Canvas 提供硬件3D加速渲染。一句话概括,通过 WebGL,可以在页端展示3D场景。

three.js 是什么

three.js 是一个基于 Javascript 能够简化 WebGL 开发的库。通过 three.js 可以极大地提高开发效率,同时降低了开发门槛,就算不熟悉图形学也可以通过 three.js 愉快地玩耍了。

技术上的实现

整个星空展示页的实现可以简单拆分为动作和场景两部分。动作主要是交互的处理和运动轨迹的计算,而场景则是简单建模和展示相关。场景可能会好玩一点,这里说明一下各部分是如何实现并组合到一起。

星空

星空背景使用的是全景展示,好像很厉害的样子但是实现起来比较简单。在空间里放置一个巨大的立方体作为容器,并将纹理图贴在六个面上,从内部观察便是全景的效果。

UC星座占卜H5(技术篇)

星座

把12个星座142个星星定位到空间里面是比较繁琐的事情。一开始的想法,是把星座布置在球体的表面,然后通过陀螺仪转动视角去寻找星座,可惜在实践中发现三轴陀螺仪在 Android 中的表现不稳定,以及这样一种交互方式不方便搜索星座,也就放弃了。而后改用简单的滑动选择星座,把星座均匀地布置在圆形的轨道上。这里每个星座具体位置的确定也比较灵活,只需要提供一个半径参数,由脚本计算提供位置坐标即可。

UC星座占卜H5(技术篇)

解决完12个星座的位置后,还有142个星星需要处理。从拿到每个星座每个星星的坐标信息,到实现出来需要经历这样的过程:Blender 导出顶点坐标,将所有的坐标换算都交给脚本处理了,由脚本产出最终位置坐标、观察坐标、星星大小等数据,再根据需要具体到某个星星做调整。

UC星座占卜H5(技术篇)

星星

具体到每个星星,一开始讨论的时候,如何表现星星发光的效果比较纠结。直接使用贴图的话没有真实的感觉,使用立体的模型又担心发光效果做的不好。于是,抱着“做出来看看先咯”这样的想法,首先做了这样子的 demo。

UC星座占卜H5(技术篇) UC星座占卜H5(技术篇)

创建一个带纹理的球体作为星星本身,再创建另一个球体包拢模拟光晕,配合星空的背景看单个星星效果还行,也能够满足绕着星星看个够的想法。可是,一旦把分散的星星组合成星座,再把相机拉远,就不是那么吸引人了。于是,舍弃了立体模型,改用贴图实现,也就是最终呈现的效果。

UC星座占卜H5(技术篇)

UC星座占卜H5(技术篇)

动作

也简单说一下是怎么实现动画。可以想象一个现实场景,一个游客拿着摄像机在公园里游玩,走到哪里拍到哪里。在这次的星空中也是这样,所有物体的坐标在一开始就确定好了,变化游走的是相机的位置和视角。

为了挪动相机,我维护了一个队列。在每次确定了起始点和结束点之后,移动路线上的所有点的坐标会被计算出来并全部推进队列中,然后在渲染每一帧的过程中抛出。至于速度曲线的变化,则把速度通过几何函数反馈到移动路线上就可以了。

UC星座占卜H5(技术篇) UC星座占卜H5(技术篇)

技术上的尝试

第一次尝试 WebGL,用身边有限的测试机子跑了一遍感觉兼容性出乎意料的好,为了兼容到旧的 Android 手机,这里使用 three.js r71 版本。可是在项目临近上线前发现兼容问题远比预想的严重。从线上返回的数据看,有接近三分之一的用户手机或浏览器因为不支持 WebGL 或者对其兼容有问题,而访问到降级页面。如果有打算将 WebGL 运用到项目里的话,需要在一开始关注如何平稳退化。

除了兼容外,资源加载也是这次遇到的比较麻烦的问题。three.js 体积较大,重新构建打包后,体积由 420kb 降到 278kb,gzip 之后 68kb。其次,星空背景使用的是贴图,也延长了首屏加载的时间,优化的方法则是复用贴图,降低请求数并减小体积。当然,通过构建一个球体作为容器也是可行的方法,但是贴图素材比较难处理。

参考资料

最后列出一些在我学习过程中帮助比较大的文章或网站,和 three.js 玩的开心!

http://webglfundamentals.org/

http://www.cnblogs.com/yiyezhai/category/446753.html

https://oncemore2020.github.io/blog/homogeneous/

http://threejs.org/
正文到此结束
Loading...