其他
2D+1D | vivo官网Web 3D应用开发与实战
作者:vivo 官网商城前端团队-Ni Huaifa
一、 前言
1.1 前端工程师,不写网页,还能做什么?
在近20年的前端发展史中,前端经历了铁器时代(小前端),信息时代(大前端)以至现在的全能前端时代。经历了几个时代的沉淀之后,前端领域开始更加细分。
目前业界普遍认为前端细分领域的垂直方向有:助力于前后端分离和工程完善的NodeJS,关注用户界面展示的小前台,提供一站式解决方案的中后台,丰富数据展示能力的数据可视化(2D、3D),以及面向未来的用户富交互体验的互动内容--AR、VR、3D等...
随着前端领域细分,前端工程师已不只是简单的负责堆砌网页、实现一些的交互,更可以在可视化领域实现一些很炫酷的效果。下图是vivo官网在3D数据可视化方面的实战展示。在线体验地址
数据可视化: 顾名思义,就是将数据以可视化图形图表等方式呈现给用户,使数据更加直观,客观,说服力更强。上图例就是利用渲染引擎对模型数据进行解析、渲染,最终呈现到移动设备。因其展现出的图像更加立体更具可交互性,属于3D数据可视化范畴。
前言 2D数据可视化 3D(2D+1D)数据可视化 vivo官网3D应用实战 总结
二、 2D数据可视化
2.1 什么是2D数据可视化?
2D数据可视化是指利用二维平面图表对数据进行组织处理、呈现的一种方式。讲到图表,大家首先想到的可能是我们日常用过柱状图,折线图等展示形式的图表图形。比如下面这种:
其实除了上面几种形式,还有一些比较炫酷的图表展示形式如:气泡图、面积图、省份地图、词云、瀑布图、漏斗图、热力图、GIS地图等。
三、3D(2D+1D)数据可视化
3.1 什么是3D数据可视化?
3D数据可视化可以理解为在2D数据可视化的基础上增加了Z轴的维度,使数据呈现从二维平面扩展到三维立体结构。是一种新的管理、分析和交互数据的方式,并且能实现实时反射、实时折射、动态阴影等高品质,逼真实时渲染3D图像。
3.2 3D数据可视化应用场景
3D数据可视化因其知识传输速度快、数据信息展示更直观、信息传达更容易,所以更加容易让使用者进行数据的理解和空间知识的呈现。
目前可见的3D数据可视化应用领域有智慧城市、汽车、手机模型展示等。
相信随着浏览器对WebGL的支持度越来越广,以及5G的普及,前端3D可视化的应用领域会越来越广泛。
下图为WebGL的渲染过程图:
1)JavaScript: 处理着色器需要的顶点坐标、法向量、颜色、纹理等信息,并为顶点着色器提供这些数据2)顶点着色器: 接收 JavaScript 传递过来的顶点信息,将顶点绘制到对应坐标3)光栅化阶段: 将图形内部区域用空像素进行填充4)片元着色器: 为图形内部的像素填充颜色信息5)渲染: 渲染到Canvas对象
WebGL既可以绘制2D数据可视化图形图表,更是一种 3D 绘图标准,这种绘图技术标准将JavaScript 和 OpenGL ES 2.0 结合在一起,通过绑定, WebGL可以为 HTML5 Canvas 提供硬件 3D 加速渲染,这样 我们就可以借助系统显卡来在浏览器里更流畅地展示 3D 场景和模型。
四、vivo官网3D应用实战
利用渲染库进行模型的渲染实现可以大大降低我们的学习成本,并且能够完成WebGL所能实现的几乎一切功能。常用的一些3D渲染库有:ThreeJs、BabylonJS、SceneJS以及CesiumJs;
模型文件其实是一个包含了顶点坐标、索引(index)、UV、法线、节点关系、材质、贴图、动画等信息的数据集合。不论模型格式如何,但是其本质就是对上述信息的编排和组织。各种模型之间的区别无非是组织的方式不同,有些用纯文本(OBJ),有些用json(GLTF),有些用二进制(FBX)。
几种不同模型文件对比:
通过对比我们发现几种模型格式分别适用于不同的场景:
1)OBJ模型对于动画的支持不是特别友好,而手机在做3D展示时需要进行一些模型的拆解动画展示。
2)FBX 由于不同引擎解析的规范不同,导致不同引擎渲染出的效果差别较大
3)GLTF(GLB) 模型格式扩展性较高,ThreeJs、Babylonjs等WebGL渲染引擎的支持性较好
分别是环境光(Ambient Light)、平行光(Directional Light)、点光源(Positional Light)。
我们分别来了解下环境光(Ambient Light)、平行光(Directional Light)、点光源(Positional Light)。
从图中我们可以看出:
平行光是朝着某个方向照射的光,光线中的每一个光子与其它光子都是平行运动的。举个例子,阳光就可以认为是平行光,平行光只能照亮物体的一部分表面。
平行光除了颜色之外,同时具有方向属性,属于有向光。有向光和物体发生作用时根据物体的材质不同,会产生漫反射和镜面反射两种反射效果。3D场景中最终的反射效果是由环境光、平行光,漫反射以及镜面反射叠加在一起的效果。
实现3D场景中的模型旋转有两种实现方式:
(2)旋转相机,即3D模型不动,相机围绕模型进行旋转
在现实生活中,将物体移动到视场中并不是正确的方法,因为在实际生活中通常是移动相机去拍摄建物体。
所以我们选择移动相机 即实现方式(1) 去实现3D实体的旋转交互。
每一次切换模型需要重新对文件进行解析,但是由于不同颜色模型间贴图等材质可以共用,所以即使切换颜色时重新加载模型并解析也会比初始加载时的速度提升很多。所以考虑到后期的固化成本与复用性,切换颜色重新加载模型文件,不失为一种相对比较优雅的处理方式。
4.2.5 全景场景搭建
在ThreeJs中全景模式可以通过加载纹理贴图的方式实现:
let texture = await Loader.loadImg(panoramicImg)
texture.encoding = THREE.sRGBEncoding
let sphereGeometry = new THREE.SphereGeometry(3000, 160, 160)
sphereGeometry.scale(-1, 1, 1)
let sphereMaterial = new THREE.MeshBasicMaterial({ map: texture })
let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
// 设置材质对象的纹理贴图
this.bgMap = sphere
this.stage.scene.add(this.bgMap)
然后加载图片数据创建材质并加入map:new THREE.MeshBasicMaterial({map:texture});new THREE.Mesh(sphereGeometry, sphereMaterial) 最终实现全景图效果。
4.3.1 模型压缩
谷歌针对GLB模型有一个压缩库Draco 3D,可以在不影响模型展示效果的情况下,对模型的体积进行压缩。可以利用GLTF Pipeline命令行对GLTF模型进行压缩。
压缩的步骤:
npm install -g gltf-pipeline
Converting a glTF to glb
gltf-pipeline -i model.gltf -o model.glb
gltf-pipeline -i model.gltf -b
4.3.2 模型解压缩
// Instantiate a loader
const loader = new GLTFLoader();
// Optional: Provide a DRACOLoader instance to decode compressed mesh data
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( '/examples/js/libs/draco/' );
loader.setDRACOLoader( dracoLoader );
首先构建一个GLTFLoader对象,然后在进行模型加载过程中,设置dracoLoader解析文件的路径,dracoLoader对压缩后的模型文件进行解析。最后将解析后的文件返回至脚本进行渲染呈现。
五、总结
本篇文章首先介绍了2D数据可视化,通过将平面图表数据可视化形式拉伸到三维立体结构,衍生出了3D数据可视化相关内容,以及官网基于ThreeJs的3D应用开发实战。
但是WebGL关于3D渲染相关的知识远不止这些。这里只是列举出了比较常用的几种3D模型的渲染要素,比如灯光,相机等。实际还有关于物体材质的光的反射类型:漫反射、镜面反射,相机也有其他类型的相机模型:例如:正交相机、立方相机、立体相机等,由于篇幅原因我们不再做详细的介绍,感兴趣的同学可以去WebGL官网去查看并学习相关内容。
END
猜你喜欢
vivo互联网技术
vivo移动互联网是基于vivo 智能手机所建立的完整移动互联网生态圈,围绕vivo大数据运营,打造包括应用、游戏、资讯、品牌、电商、内容、金融、搜索的全方位服务生态,满足海量用户的多样化需求。
点一下,代码无 Bug