2D+1D | vivo官網(wǎng)Web 3D應(yīng)用開發(fā)與實(shí)戰(zhàn)

一、 前言

1.1 前端工程師,不寫網(wǎng)頁,還能做什么?

在近20年的前端發(fā)展史中,前端經(jīng)歷了鐵器時(shí)代(小前端),信息時(shí)代(大前端)以至現(xiàn)在的全能前端時(shí)代。經(jīng)歷了幾個(gè)時(shí)代的沉淀之后,前端領(lǐng)域開始更加細(xì)分。

目前業(yè)界普遍認(rèn)為前端細(xì)分領(lǐng)域的垂直方向有:助力于前后端分離和工程完善的NodeJS,關(guān)注用戶界面展示的小前臺(tái),提供一站式解決方案的中后臺(tái),豐富數(shù)據(jù)展示能力的數(shù)據(jù)可視化(2D、3D),以及面向未來的用戶富交互體驗(yàn)的互動(dòng)內(nèi)容--AR、VR、3D等...

隨著前端領(lǐng)域細(xì)分,前端工程師已不只是簡單的負(fù)責(zé)堆砌網(wǎng)頁、實(shí)現(xiàn)一些的交互,更可以在可視化領(lǐng)域?qū)崿F(xiàn)一些很炫酷的效果。下圖是vivo官網(wǎng)在3D數(shù)據(jù)可視化方面的實(shí)戰(zhàn)展示。在線體驗(yàn)地址

vivo官網(wǎng)3D數(shù)據(jù)可視化實(shí)戰(zhàn)圖例

數(shù)據(jù)可視化: 顧名思義,就是將數(shù)據(jù)以可視化圖形圖表等方式呈現(xiàn)給用戶,使數(shù)據(jù)更加直觀,客觀,說服力更強(qiáng)。上圖例就是利用渲染引擎對(duì)模型數(shù)據(jù)進(jìn)行解析、渲染,最終呈現(xiàn)到移動(dòng)設(shè)備。因其展現(xiàn)出的圖像更加立體更具可交互性,屬于3D數(shù)據(jù)可視化范疇。

今天我們就一起來了解一下前端的一個(gè)細(xì)化分支--3D數(shù)據(jù)可視化。本篇文章主要分為:

  • 前言
  • 2D數(shù)據(jù)可視化
  • 3D(2D+1D)數(shù)據(jù)可視化
  • vivo官網(wǎng)3D應(yīng)用實(shí)戰(zhàn)
  • 總結(jié)

希望通過五個(gè)章節(jié)的介紹和探討,能夠可以讓大家對(duì)數(shù)據(jù)可視化以及3D數(shù)據(jù)可視化有一個(gè)較為清晰的了解。

二、 2D數(shù)據(jù)可視化

2.1 什么是2D數(shù)據(jù)可視化?

2D數(shù)據(jù)可視化是指利用二維平面圖表對(duì)數(shù)據(jù)進(jìn)行組織處理、呈現(xiàn)的一種方式。講到圖表,大家首先想到的可能是我們?nèi)粘S眠^柱狀圖,折線圖等展示形式的圖表圖形。比如下面這種:

注:圖片來自網(wǎng)絡(luò)(谷歌圖片搜索)

其實(shí)除了上面幾種形式,還有一些比較炫酷的圖表展示形式如:氣泡圖、面積圖、省份地圖、詞云、瀑布圖、漏斗圖、熱力圖、GIS地圖等。

2.2 2D數(shù)據(jù)可視化應(yīng)用場景

2D數(shù)據(jù)可視化在工作生活中的應(yīng)用非常廣泛。最簡單的像Excel數(shù)據(jù)圖表,XMind、Visio屬于數(shù)據(jù)可視化的具體應(yīng)用場景。也有一些稍微復(fù)雜的,比如數(shù)據(jù)可視化大屏,后臺(tái)數(shù)據(jù)報(bào)表,地圖等。

注:圖片來自網(wǎng)絡(luò)(谷歌圖片搜索)

隨著數(shù)據(jù)可視化的應(yīng)用場景越來越廣泛,數(shù)據(jù)可以呈現(xiàn)為更多豐富的可視化形式,使用戶能夠更加輕易、便捷的獲取并理解數(shù)據(jù)傳達(dá)的信息。

三、3D(2D+1D)數(shù)據(jù)可視化

3.1 什么是3D數(shù)據(jù)可視化?

3D數(shù)據(jù)可視化可以理解為在2D數(shù)據(jù)可視化的基礎(chǔ)上增加了Z軸的維度,使數(shù)據(jù)呈現(xiàn)從二維平面擴(kuò)展到三維立體結(jié)構(gòu)。是一種新的管理、分析和交互數(shù)據(jù)的方式,并且能實(shí)現(xiàn)實(shí)時(shí)反射、實(shí)時(shí)折射、動(dòng)態(tài)陰影等高品質(zhì),逼真實(shí)時(shí)渲染3D圖像。

3D數(shù)據(jù)可視化與2D數(shù)據(jù)可視化(一般數(shù)據(jù)可視化)主要區(qū)別就是更立體,更真實(shí),更有沉浸感。來張圖感受一下:

注:圖片來自網(wǎng)絡(luò)(https://www.hightopo.com)

3.2 3D數(shù)據(jù)可視化應(yīng)用場景

3D數(shù)據(jù)可視化因其知識(shí)傳輸速度快、數(shù)據(jù)信息展示更直觀、信息傳達(dá)更容易,所以更加容易讓使用者進(jìn)行數(shù)據(jù)的理解和空間知識(shí)的呈現(xiàn)。

目前可見的3D數(shù)據(jù)可視化應(yīng)用領(lǐng)域有智慧城市、汽車、手機(jī)模型展示等。

注:圖片來自網(wǎng)絡(luò)(https://www.hightopo.com)

相信隨著瀏覽器對(duì)WebGL的支持度越來越廣,以及5G的普及,前端3D可視化的應(yīng)用領(lǐng)域會(huì)越來越廣泛。

3.3 3D數(shù)據(jù)可視化解決方案

了解了3D數(shù)據(jù)可視化的概念和應(yīng)用場景,我們?cè)賮砹私庀履壳皹I(yè)界3D數(shù)據(jù)可視化主流解決方案:WebGL。

下圖為WebGL的渲染過程圖:

注:圖片來自vivo官網(wǎng)前端團(tuán)隊(duì)

WebGL(Web Graphics Library) 是基于 OpenGL ES 規(guī)范的瀏覽器實(shí)現(xiàn),上圖的WebGL渲染過程可以理解為:

1)JavaScript: 處理著色器需要的頂點(diǎn)坐標(biāo)、法向量、顏色、紋理等信息,并為頂點(diǎn)著色器提供這些數(shù)據(jù)
2)頂點(diǎn)著色器: 接收 JavaScript 傳遞過來的頂點(diǎn)信息,將頂點(diǎn)繪制到對(duì)應(yīng)坐標(biāo)
3)光柵化階段: 將圖形內(nèi)部區(qū)域用空像素進(jìn)行填充
4)片元著色器: 為圖形內(nèi)部的像素填充顏色信息
5)渲染: 渲染到Canvas對(duì)象

WebGL既可以繪制2D數(shù)據(jù)可視化圖形圖表,更是一種 3D 繪圖標(biāo)準(zhǔn),這種繪圖技術(shù)標(biāo)準(zhǔn)將JavaScript 和 OpenGL ES 2.0 結(jié)合在一起,通過綁定, WebGL可以為 HTML5 Canvas 提供硬件 3D 加速渲染,這樣 我們就可以借助系統(tǒng)顯卡來在瀏覽器里更流暢地展示 3D 場景和模型。

四、vivo官網(wǎng)3D應(yīng)用實(shí)戰(zhàn)

對(duì)用戶來講,網(wǎng)上購物最大的痛點(diǎn)就是不能所見即所得,目前主流的網(wǎng)上商城一般都是通過圖片或者視頻展示產(chǎn)品的特點(diǎn),而這些二維的信息展示方式無法讓用戶很好的去了解產(chǎn)品的信息。有了3D展示場景之后,用戶通過手機(jī)模型的3D展示可以更加直觀清楚的了解手機(jī)的產(chǎn)品細(xì)節(jié)及特點(diǎn),從而提升用戶的購買欲望。

下面我們一起來了解下vivo官網(wǎng)在實(shí)現(xiàn)3D展示時(shí)的技術(shù)選型及實(shí)現(xiàn)方案。

4.1 可視化工具介紹及技術(shù)選型

目前,業(yè)界已經(jīng)有很多好用的3D可視化開發(fā)工具,方便我們進(jìn)行3D可視化需求的開發(fā)。3D數(shù)據(jù)可視化主要包含渲染庫和模型兩方面,下面我們從3D渲染庫和模型分別了解下3D可視化領(lǐng)域工具及官網(wǎng)的技術(shù)選型。

4.1.1 渲染庫選型

目前實(shí)現(xiàn)3D數(shù)據(jù)可視化的主流解決方案是基于WebGL,那既然有了WebGL,我們?yōu)槭裁催€需要渲染庫?

這是因?yàn)閃ebGL門檻相對(duì)較高,需要理解掌握相對(duì)較多的數(shù)學(xué)知識(shí)。雖然WebGL提供的是面向前端的API,但本質(zhì)上WebGL跟前端開發(fā)完全是兩個(gè)不同的方向,知識(shí)的重疊很少。

利用渲染庫進(jìn)行模型的渲染實(shí)現(xiàn)可以大大降低我們的學(xué)習(xí)成本,并且能夠完成WebGL所能實(shí)現(xiàn)的幾乎一切功能。常用的一些3D渲染庫有:ThreeJs、BabylonJS、SceneJS以及CesiumJs;

幾種不同3D渲染庫對(duì)比:

注:圖片來自vivo官網(wǎng)前端團(tuán)隊(duì)

通過對(duì)比我們可以發(fā)現(xiàn),上述幾種渲染庫各有優(yōu)點(diǎn)。但是在做手機(jī)模型的3D渲染時(shí),對(duì)于光照和陰影以及反射的側(cè)重點(diǎn)比較高,并不需要碰撞檢測(cè)等特性。所以,基于以上的對(duì)比,我們選取ThreeJs作為我們3D渲染的底層庫去實(shí)現(xiàn)手機(jī)模型的3D渲染。

4.1.2 模型選型

了解了渲染庫,我們?cè)賮砹囊涣某S玫?D模型格式:OBJ、FBX、GLTF。

模型文件其實(shí)是一個(gè)包含了頂點(diǎn)坐標(biāo)、索引(index)、UV、法線、節(jié)點(diǎn)關(guān)系、材質(zhì)、貼圖、動(dòng)畫等信息的數(shù)據(jù)集合。不論模型格式如何,但是其本質(zhì)就是對(duì)上述信息的編排和組織。各種模型之間的區(qū)別無非是組織的方式不同,有些用純文本(OBJ),有些用json(GLTF),有些用二進(jìn)制(FBX)。

幾種不同模型文件對(duì)比:

注:圖片來自vivo官網(wǎng)前端團(tuán)隊(duì)

通過對(duì)比我們發(fā)現(xiàn)幾種模型格式分別適用于不同的場景:

1)OBJ模型對(duì)于動(dòng)畫的支持不是特別友好,而手機(jī)在做3D展示時(shí)需要進(jìn)行一些模型的拆解動(dòng)畫展示。
2)FBX 由于不同引擎解析的規(guī)范不同,導(dǎo)致不同引擎渲染出的效果差別較大
3)GLTF(GLB) 模型格式擴(kuò)展性較高,ThreeJs、Babylonjs等WebGL渲染引擎的支持性較好

4.2 3D場景搭建及方案實(shí)施

我們發(fā)現(xiàn),如果想要將3D場景中的物體展示的足夠逼真,相機(jī)和光照是必不可少的兩個(gè)基本要素。實(shí)際業(yè)務(wù)場景中還有模型顏色切換、模型旋轉(zhuǎn)、縮放、全景場景等邏輯需要我們?nèi)ヌ幚怼?/p>

4.2.1 場景相機(jī)

首先,我們來了解一下相機(jī)。3D場景中的相機(jī)類似于現(xiàn)實(shí)生活中的人眼的功能。相機(jī)拍攝一個(gè)物體的時(shí)候相機(jī)的位置和角度需要設(shè)置,虛擬的相機(jī)還需要設(shè)置投影方式。位置和角度我們比較好理解,下面我們來介紹下投影方式:投影有兩種方式,分別是正投影與透視投影:

4.2.1.1 正投影

正投影: 正射投影,又叫平行投影。這種投影的視景體是一個(gè)矩形的平行管道,也就是一個(gè)長方體,如圖所示。正射投影的最大一個(gè)特點(diǎn)是無論物體距離相機(jī)多遠(yuǎn),投影后的物體大小尺寸不變。

注:圖片來自網(wǎng)絡(luò)(http://m.dingjisc.com)

正投影通常用在建筑藍(lán)圖繪制和計(jì)算機(jī)輔助設(shè)計(jì)等平面圖形方面,這些行業(yè)要求投影后的物體尺寸及相互間的角度不變,以便施工或制造時(shí)物體比例大小正確。

4.2.1.2 透視投影

透視投影: 透視投影符合人們心理習(xí)慣,即離視點(diǎn)近的物體大,離視點(diǎn)遠(yuǎn)的物體小,遠(yuǎn)到極點(diǎn)即為消失,成為滅點(diǎn)。它的視景體類似于一個(gè)頂部和底部都被切除掉的棱椎,也就是棱臺(tái)。

注:圖片來自網(wǎng)絡(luò)(https://blog.csdn.net)

透視投影通常用于動(dòng)畫、視覺仿真以及其它許多具有真實(shí)性反映的方面。相比較來講,透視投影則更接近我們的視覺感知。所以在官網(wǎng)的手機(jī)模型3D展示中,我們選擇透視投影來計(jì)算相機(jī)的投影矩陣。

4.2.2 場景光照

要想讓我們渲染出的 3D 物體看起來更自然、逼真,很重要的一點(diǎn)就是模擬各種光照的效果。

3D場景中物體的光照由光源、介質(zhì)(物體的材質(zhì))和反射類型決定的,而反射類型又由物體的材質(zhì)特點(diǎn)決定。根據(jù)不同的光源特點(diǎn),我們可以將光源分為 4 種不同的類型。

分別是環(huán)境光(Ambient Light)、平行光(Directional Light)、點(diǎn)光源(Positional Light)。

我們分別來了解下環(huán)境光(Ambient Light)、平行光(Directional Light)、點(diǎn)光源(Positional Light)。

注:圖片來自網(wǎng)絡(luò)(https://blog.csdn.net)

從圖中我們可以看出:

平行光是朝著某個(gè)方向照射的光,光線中的每一個(gè)光子與其它光子都是平行運(yùn)動(dòng)的。舉個(gè)例子,陽光就可以認(rèn)為是平行光,平行光只能照亮物體的一部分表面。

平行光除了顏色之外,同時(shí)具有方向?qū)傩裕瑢儆谟邢蚬?。有向光和物體發(fā)生作用時(shí)根據(jù)物體的材質(zhì)不同,會(huì)產(chǎn)生漫反射和鏡面反射兩種反射效果。3D場景中最終的反射效果是由環(huán)境光、平行光,漫反射以及鏡面反射疊加在一起的效果。

點(diǎn)光源是指光線是從一個(gè)點(diǎn)發(fā)射出來的,是向著四面八方發(fā)射的。這種光在我們的現(xiàn)實(shí)生活中是最常被用到的。舉個(gè)例子,電燈泡就是向各個(gè)方向發(fā)射光線的,它就可以被認(rèn)作是點(diǎn)光源。

點(diǎn)光源不僅有方向?qū)傩?,還有位置屬性。因此計(jì)算點(diǎn)光源的光照,我們要先根據(jù)光源位置和物體表面相對(duì)位置來確定方向,然后再和平行光一樣,計(jì)算光的方向和物體表面法向的夾角。

環(huán)境光就是指物體所在的三維空間中天然的光,它充滿整個(gè)空間,在每一處的光照強(qiáng)度都一樣。環(huán)境光沒有方向,所以,物體表面反射環(huán)境光的效果,只和環(huán)境光本身以及材質(zhì)的反射率有關(guān)。

4.2.3 模型旋轉(zhuǎn)實(shí)現(xiàn)

有了相機(jī)和光照就能夠比較逼真的將模型呈現(xiàn)給用戶了,但是還需要處理模型本身的一些交互操作,比如模型旋轉(zhuǎn)、顏色切換等。

實(shí)現(xiàn)3D場景中的模型旋轉(zhuǎn)有兩種實(shí)現(xiàn)方式:

(1)3D場景中的相機(jī)不動(dòng),旋轉(zhuǎn)3D實(shí)體即3D模型

注:圖片來自網(wǎng)絡(luò)(https://webglfundamentals.org)

(2)旋轉(zhuǎn)相機(jī),即3D模型不動(dòng),相機(jī)圍繞模型進(jìn)行旋轉(zhuǎn)

注:圖片來自網(wǎng)絡(luò)(https://webglfundamentals.org)

在現(xiàn)實(shí)生活中,將物體移動(dòng)到視場中并不是正確的方法,因?yàn)樵趯?shí)際生活中通常是移動(dòng)相機(jī)去拍攝建物體。所以我們選擇移動(dòng)相機(jī) 即實(shí)現(xiàn)方式(1) 去實(shí)現(xiàn)3D實(shí)體的旋轉(zhuǎn)交互。

4.2.4 模型顏色切換

模型格式采用的是GLB模型(方便后期固化上傳),所以每一種顏色對(duì)應(yīng)一個(gè)新的GLB文件。

每一次切換模型需要重新對(duì)文件進(jìn)行解析,但是由于不同顏色模型間貼圖等材質(zhì)可以共用,所以即使切換顏色時(shí)重新加載模型并解析也會(huì)比初始加載時(shí)的速度提升很多。所以考慮到后期的固化成本與復(fù)用性,切換顏色重新加載模型文件,不失為一種相對(duì)比較優(yōu)雅的處理方式。

注:圖片來自vivo官網(wǎng)前端團(tuán)隊(duì)

4.2.5 全景場景搭建

為了讓用戶在瀏覽產(chǎn)品的3D頁面時(shí)有更強(qiáng)的沉浸體驗(yàn)。我們采用了全景模式。用戶在全景模式下旋轉(zhuǎn)縮放手機(jī)時(shí),對(duì)應(yīng)的背景元素同樣會(huì)跟隨相機(jī)的旋轉(zhuǎn)和縮放進(jìn)行旋轉(zhuǎn)縮放。這樣用戶在進(jìn)行瀏覽查看時(shí),交互的體驗(yàn)感更強(qiáng)。

在ThreeJs中全景模式可以通過加載紋理貼圖的方式實(shí)現(xiàn):

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)

// 設(shè)置材質(zhì)對(duì)象的紋理貼圖
this.bgMap = sphere
this.stage.scene.add(this.bgMap)

上面代碼首先創(chuàng)建一個(gè)球形幾何SphereGeometry,將創(chuàng)建后的球形幾何網(wǎng)格進(jìn)行x軸反轉(zhuǎn):sphereGeometry.scale(-1, 1, 1),使所有的面點(diǎn)向內(nèi)。然后加載圖片數(shù)據(jù)創(chuàng)建材質(zhì)并加入map:new THREE.MeshBasicMaterial({map:texture});new THREE.Mesh(sphereGeometry, sphereMaterial) 最終實(shí)現(xiàn)全景圖效果。

4.3 性能優(yōu)化

4.3.1 模型壓縮

為了提升頁面初始化的加載速度以及切換顏色模型時(shí)的解析速度,我們?cè)谥谱魍瓿赡P秃?,需要?duì)模型進(jìn)行壓縮以降低模型的體積量。

谷歌針對(duì)GLB模型有一個(gè)壓縮庫Draco 3D,可以在不影響模型展示效果的情況下,對(duì)模型的體積進(jìn)行壓縮。可以利用GLTF Pipeline命令行對(duì)GLTF模型進(jìn)行壓縮。

壓縮的步驟:

1、安裝gltf-pipeline

npm install -g gltf-pipeline

2、轉(zhuǎn)換gltf至glb文件

Converting a glTF to glb
gltf-pipeline -i model.gltf -o model.glb

gltf-pipeline -i model.gltf -b

壓縮之后,glb文件的體積會(huì)減少80%左右,所以在加載速度和效果呈現(xiàn)上會(huì)比原始的GLTF文件更快。

注:圖片來自網(wǎng)絡(luò)(https://cesium.com)

4.3.2 模型解壓縮

ThreeJs有針對(duì)壓縮模型的解壓縮方案:

// 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 );

首先構(gòu)建一個(gè)GLTFLoader對(duì)象,然后在進(jìn)行模型加載過程中,設(shè)置dracoLoader解析文件的路徑,dracoLoader對(duì)壓縮后的模型文件進(jìn)行解析。最后將解析后的文件返回至腳本進(jìn)行渲染呈現(xiàn)。

五、總結(jié)

本篇文章首先介紹了2D數(shù)據(jù)可視化,通過將平面圖表數(shù)據(jù)可視化形式拉伸到三維立體結(jié)構(gòu),衍生出了3D數(shù)據(jù)可視化相關(guān)內(nèi)容,以及官網(wǎng)基于ThreeJs的3D應(yīng)用開發(fā)實(shí)戰(zhàn)。

但是WebGL關(guān)于3D渲染相關(guān)的知識(shí)遠(yuǎn)不止這些。這里只是列舉出了比較常用的幾種3D模型的渲染要素,比如燈光,相機(jī)等。實(shí)際還有關(guān)于物體材質(zhì)的光的反射類型:漫反射、鏡面反射,相機(jī)也有其他類型的相機(jī)模型:例如:正交相機(jī)、立方相機(jī)、立體相機(jī)等,由于篇幅原因我們不再做詳細(xì)的介紹,感興趣的同學(xué)可以去(WebGL)官網(wǎng)去查看并學(xué)習(xí)相關(guān)內(nèi)容。

作者:vivo 官網(wǎng)商城前端團(tuán)隊(duì)-Ni Huaifa

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容