首页 > 代码库 > 第六章 大数据,6.3 突破传统,4k大屏的沉浸式体验(作者: 彦川、小丛)
第六章 大数据,6.3 突破传统,4k大屏的沉浸式体验(作者: 彦川、小丛)
6.3 突破传统,4k大屏的沉浸式体验
前言
能够在 4K 的页面上表演,对设计师和前端开发来说,即是机会也是挑战,我们可以有更大的空间设计宏观的场景,炫酷的转场,让观众感受影院式视觉体验,但是,又必须面对因为画布变大带来的性能问题,以及绞尽脑汁实现很多天马行空的的想法。下面是这次双11媒体大屏开发中我们的一些设计和思路。
1. 3D动感跑道
当逍遥子零点倒数5,4,3,2,1,0!激昂音乐奏起,媒体中心大屏幕跳跃出一个动感十足的页面,黄橙橙的 GMV 数字蹭蹭往上长,跳跃的翻牌器下有个不断向前延伸的跑道,两旁错落有致的建筑群,顶部有一簇簇如烟花般四面飞散的点状射线...
1.1 场景设计
场景包括三个部分:红色的猫门,左右两旁的建筑群,底下的炫彩跑道。基本结构如下:
1.2 构建 3D 模型
基于WebGL技术,以其中的几何体构建出一个个 3D模型,为了使得建筑群错落有致,逐一调整每幢建筑的位置(调整 position 中的 x,y,z 值)
对于不规则的建筑模型,采用多种几何体拼凑的形式
1.3 给建筑“穿上衣服”
现在的建筑还是死气沉沉的几何体,给每幢建筑渲染不同的图片材质后,便灵动起来了。
最后给猫门和跑道都渲染上材质,一个完整的场景便构建出来了。
1.4 “跑起来吧!”
整体的动效设计是:沿着炫彩跑道不断向前冲刺,迎面而来的建筑群给观众一种强烈的视觉冲击之感。开发思路:
(1) 猫门+跑道+左右建筑为一个整体,复制两组,沿着 z 轴依次摆放;
(2) 摄像机的 z 值在不断前进,即不断累加;
(3) 当摄像机的 z 值超过一组模型的 z 值时候,重置该组的 z 值,移至末端。以此往复。
2. 可形变的地图
地图是展现大数据可视化的最好背景,没有之一。一般情况下,可视化地图场景分为 3D 球面和 2.5D 平面两种,以前两者往往是隔绝开来的,根据展示数据的维度选择一种,比如讲全球贸易时,用球面场景的页面,讲国家贸易时,切换到 2.5D 平面场景的页面。多页面切换严重影响了阅读数据的连贯性,不符合讲故事的风格。因此,我们利用 WebGL 设计了一个可形变的地图,把场景集中在一个页面展示。
在 3D 的世界里,首先有的是点,其次是线和面,不管是平面地图还是球面地图,它们的本质都是点的集合,如果控制了点,就控制了 3D 世界的变化。我们的变形地图是一个由无数点组成的对象,通过GLSL(OpenGL Shading Language)语言,我们可以动态改变地图上点的位置。
举个简单的例子,在平面地图中,北京在世界坐标系中的位置是 P, 在球形地图中,北京在相同世界坐标系中的位置是 Q,那么从平面到球面的形变过程,其实就是 P 点到 Q 点的移动,反之亦然。推广到所有组成平面的点,形变的本质就是所有点移动到目的地点的过程。我们分别对所有点的起点(平面点)和终点(球面点)进行线性插值,就可以得到每个点的形变路径,剩下的事情就是加个缓动函数,让点运动起来。
3. 灵活的飞线
飞线代表着交易,一条飞线的飞出代表一笔订单的完成,给人非常直观的可视化体验,为了从不同维度展现交易,飞线的场景也很多,比如:
球面场景:
平面场景:
为了保证 4K 页面下有足够的帧率,以及灵活应对球面与平面的切换,我们对飞线进行了重新设计。首先是把飞线组件从业务中解耦出来,飞线组件不管数据的更新、缓存,只是单纯接受发生交易的起终点经纬度以及展示形式(球面或者平面)等参数,然后绘制一条飞行轨迹;其次,对飞线组件进行了优化,飞线的实现方式很多,可以是点集合不动,让颜色在点集合上流动,或者是事先给点集合赋值颜色,然后移动点,不同的实现方式,性能也会不同。理论和实践得出:所有飞线只用一个几何体, 且这个几何体的点数尽可能少对帧率提高有极大的帮助。
上图是我们设计的飞线组件 ShootPool,发射一条飞线的时候,仅仅需要知道飞线的起点 startPos,和 endPos,ShootPool 的工作机制如下:
(1) 假设飞线组件最大支持 n 条飞线,每条飞线长度为 30 个点,飞行路径为 100 个点,那么几何体的点数为 n x 30,路径总长 n x 100。
(2) 当外部调用了 ShootPool 的 run 方法时,组件会根据当前展示形式计算出这条飞线的整个飞行线路,如果这个时候飞线池是不满的,有路径(路径和飞线是对应的)处于 Iddle 状态,如图中 100~199的点,则将这条 Iddle 路径更新,状态改变为 Active。
(3) 找到当前路径对应的几何体的片段,通过缓动函数,使得当前片段(一条飞线)沿着路径移动,产生飞行效果。
(4) 当飞线末端到达路径的末端时,设置当前路径为 Iddle,等待下一条飞线。
这个场景可以理解为飞机延着航线飞行,每条航线配备一架飞机,因为有钱任性,只要有飞机空着,就可以重新制定航线起飞。
新飞线组件的优势在于:只有一个几何体,几何体上没有冗余的点,可以保证飞线的性能是最优的,另外飞线的颜色和路径都是起飞前重新设定的,面对变化场景时,显得非常灵活。
4. 会呼吸的热力点
地图上的热力点大小代表着地区的交易量,同时,为了营造一种买买买的热闹气氛,每个点都是在呼吸的。对于重复简单的粒子,一般都采用WebGL 的粒子系统来实现,因为每个点只是一张图片,而不单独需要几何体,所以,可以展现非常多的点。为了实现呼吸效果,我们依然采用WebGL 和 GLSL 配合的方式来实现,这样就可以用 GLSL 来动态改变点的大小,思路和飞线的实现方式类似。
Particles 组件接收 points 数组作为参数,points 的每个节点信息用来确定热力点在场景中的位置,以及每个点的 max size。组件会根据 max size 和时间轴计算出当前热力点的大小(也可以是透明度), 然后传递给GLSL,这样,GPU 在绘制点的时候,就有大小的区分,随着时间推移,大小发生周期性变化(比如 sin 函数),从而实现呼吸的效果。
5. 粒子风格的地球
今年大屏地图的风格是粒子风格,粒子组成的地球,高亮的中国板块,以及高亮的省份,要实现上图的效果,我们用了贴图。为什么不用真正的粒子?如果每个点都用几何体来实现,GPU需要绘制的顶点数 n * m,n 为粒子数,数量级为万,m 为每个几何体的顶点个数,一般为几十个,性能堪忧。如果利用 WebGL 的粒子系统,性能上应该是可以的,GPU 绘制的顶点个数为 n * 1,可以用 5w 左右的点将世界地图拼出来,见下图。但是粒子的本质是只是一张图片,不是由几何体构成的,所以,我们改变不了每个粒子永远看着摄像机的尴尬, 另外,如果设计师如果觉得粒子大小还要小 x倍,那么粒子点数就需要 5x 万个,是不是很提心吊胆。
利用贴图的好处在于,可以最大限度地还原设计师的效果,同时几乎不影响性能,性价比相当高。在区域屏省份特写轮换以及国家屏切换时,需要动态改变高亮的区域。要实现这一功能,我们事先准备好一张高亮的地图,通过省份或者国家轮廓的经纬度,将仅包含我们需要的区域用 canvas 绘制出来,制做成新贴图,然后替换掉老的贴图即可,记住老的贴图必须手动释放内存, 不然 GPU 内存会溢出哦。
6. 如烟花般四面飞散点状射线
在这个热闹非凡的节日之中,怎能没有烟花流线来助兴呢?
开发思路:
(1) 初始化一张与屏幕等宽的 canvas 画布;
(2) 以中心点为坐标轴原心,射线由原心发出,向四周扩散;
(3) 不断随机生成终点位置,当射线到达终点位置后,销毁该射线;
射线是由一系列透明度递减的圆点组成。
其中使用了一个小技巧:
(1) 把画笔的透明度设置为小于1,如 0.85;ctx.globalAlpha = 0.85;
(2) 创建一张虚拟("虚拟"是指仅在 js 里使用它,而不放进 document 中)的 canvas 画布;
每一帧的动画渲染步骤如下:
(1) 在虚拟画布中存储上一帧的动画状态(ctx.drawImage);
(2) 清空当前画布(ctx.clearRect);
(3) 绘制新的圆点(ctx.arc);
(4) 把虚拟画布中的内容复制回当前画布(ctx.drawImage)。
注意此时到由于设置了画笔透明度,重新绘制在画布中的图像整体透明度将降低 0.15 度。
总结
今年的媒体大屏有两个特点:屏多,多达 20 多张屏,屏大,基本所有的屏都是 4K,所以挑战还蛮大的,为了提高开发效率,大部分动效的实现方式遵循简单、高效的原则,所幸视觉还原效果还是符合预期的。文中涉及 3D 可视化技术比较多,其实还有很多 2D 的图表,比如战略屏大地球上的 gmv柱子也是花费了设计师和开发的很多心思,篇幅有限就不一一叙述。今年是团队第一次参与双11媒体大屏的开发,以后的路希望越走越长。
第六章 大数据,6.3 突破传统,4k大屏的沉浸式体验(作者: 彦川、小丛)