2D+1D | vivo官網Web 3D應用開發與實戰

vivo網際網路技術發表於2021-04-12

一、 前言

1.1 前端工程師,不寫網頁,還能做什麼?

在近20年的前端發展史中,前端經歷了鐵器時代(小前端),資訊時代(大前端)以至現在的全能前端時代。經歷了幾個時代的沉澱之後,前端領域開始更加細分。

目前業界普遍認為前端細分領域的垂直方向有:助力於前後端分離和工程完善的NodeJS,關注使用者介面展示的小前臺,提供一站式解決方案的中後臺,豐富資料展示能力的資料視覺化(2D、3D),以及面向未來的使用者富互動體驗的互動內容--AR、VR、3D等...

隨著前端領域細分,前端工程師已不只是簡單的負責堆砌網頁、實現一些的互動,更可以在視覺化領域實現一些很炫酷的效果。下圖是vivo官網在3D資料視覺化方面的實戰展示。

2D+1D | vivo官網Web 3D應用開發與實戰

vivo官網3D資料視覺化實戰圖例

資料視覺化: 顧名思義,就是將資料以視覺化圖形圖表等方式呈現給使用者,使資料更加直觀,客觀,說服力更強。上圖例就是利用渲染引擎對模型資料進行解析、渲染,最終呈現到移動裝置。因其展現出的影像更加立體更具可互動性,屬於3D資料視覺化範疇。

今天我們就一起來了解一下前端的一個細化分支--3D資料視覺化。本篇文章主要分為:

  • 前言

  • 2D資料視覺化

  • 3D(2D+1D)資料視覺化

  • vivo官網3D應用實戰

  • 總結

希望透過五個章節的介紹和探討,能夠可以讓大家對資料視覺化以及3D資料視覺化有一個較為清晰的瞭解。

二、 2D資料視覺化

2.1 什麼是2D資料視覺化?

2D資料視覺化是指利用二維平面圖表對資料進行組織處理、呈現的一種方式。講到圖表,大家首先想到的可能是我們日常用過柱狀圖,折線圖等展示形式的圖表圖形。比如下面這種:

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路(谷歌圖片搜尋)

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

2.2 2D資料視覺化應用場景

2D資料視覺化在工作生活中的應用非常廣泛。最簡單的像Excel資料圖表,XMind、Visio屬於資料視覺化的具體應用場景。也有一些稍微複雜的,比如資料視覺化大屏,後臺資料包表,地圖等。

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路(谷歌圖片搜尋)

隨著資料視覺化的應用場景越來越廣泛,資料可以呈現為更多豐富的視覺化形式,使使用者能夠更加輕易、便捷的獲取並理解資料傳達的資訊。

三、3D(2D+1D)資料視覺化

3.1 什麼是3D資料視覺化?

3D資料視覺化可以理解為在2D資料視覺化的基礎上增加了Z軸的維度,使資料呈現從二維平面擴充套件到三維立體結構。是一種新的管理、分析和互動資料的方式,並且能實現實時反射、實時折射、動態陰影等高品質,逼真實時渲染3D影像。

3D資料視覺化與2D資料視覺化(一般資料視覺化)主要區別就是更立體,更真實,更有沉浸感。來張圖感受一下:

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路

3.2 3D資料視覺化應用場景

3D資料視覺化因其知識傳輸速度快、資料資訊展示更直觀、資訊傳達更容易,所以更加容易讓使用者進行資料的理解和空間知識的呈現。

目前可見的3D資料視覺化應用領域有智慧城市、汽車、手機模型展示等。

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路

相信隨著瀏覽器對WebGL的支援度越來越廣,以及5G的普及,前端3D視覺化的應用領域會越來越廣泛。

3.3 3D資料視覺化解決方案

瞭解了3D資料視覺化的概念和應用場景,我們再來了解下目前業界3D資料視覺化主流解決方案:WebGL。

下圖為WebGL的渲染過程圖:

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自vivo官網前端團隊

WebGL(Web Graphics Library) 是基於 OpenGL ES 規範的瀏覽器實現,上圖的WebGL渲染過程可以理解為:

1) JavaScript:  處理著色器需要的頂點座標、法向量、顏色、紋理等資訊,併為頂點著色器提供這些資料

2) 頂點著色器: 接收 JavaScript 傳遞過來的頂點資訊,將頂點繪製到對應座標

3) 光柵化階段: 將圖形內部區域用空畫素進行填充

4) 片元著色器: 為圖形內部的畫素填充顏色資訊

5) 渲染: 渲染到Canvas物件

WebGL既可以繪製2D資料視覺化圖形圖表,更是一種 3D 繪圖示準,這種繪圖技術標準將JavaScript 和 OpenGL ES 2.0 結合在一起,透過繫結, WebGL可以為 HTML5 Canvas 提供硬體 3D 加速渲染,這樣 我們就可以藉助系統顯示卡來在瀏覽器裡更流暢地展示 3D 場景和模型。


四、vivo官網3D應用實戰

對使用者來講,網上購物最大的痛點就是不能所見即所得,目前主流的網上商城一般都是透過圖片或者影片展示產品的特點,而這些二維的資訊展示方式無法讓使用者很好的去了解產品的資訊。有了3D展示場景之後,使用者透過手機模型的3D展示可以更加直觀清楚的瞭解手機的產品細節及特點,從而提升使用者的購買慾望。

下面我們一起來了解下vivo官網在實現3D展示時的技術選型及實現方案。

4.1 視覺化工具介紹及技術選型

目前,業界已經有很多好用的3D視覺化開發工具,方便我們進行3D視覺化需求的開發。3D資料視覺化主要包含渲染庫和模型兩方面,下面我們從3D渲染庫和模型分別瞭解下3D視覺化領域工具及官網的技術選型。

4.1.1 渲染庫選型

目前實現3D資料視覺化的主流解決方案是基於WebGL,那既然有了WebGL,我們為什麼還需要渲染庫?

這是因為WebGL門檻相對較高,需要理解掌握相對較多的數學知識。雖然WebGL提供的是面向前端的API,但本質上WebGL跟前端開發完全是兩個不同的方向,知識的重疊很少。

利用渲染庫進行模型的渲染實現可以大大降低我們的學習成本,並且能夠完成WebGL所能實現的幾乎一切功能。常用的一些3D渲染庫有: ThreeJs、BabylonJS、SceneJS以及 CesiumJs;

幾種不同3D渲染庫對比:

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自vivo官網前端團隊

透過對比我們可以發現,上述幾種渲染庫各有優點。但是在做手機模型的3D渲染時,對於光照和陰影以及反射的側重點比較高,並不需要碰撞檢測等特性。所以,基於以上的對比,我們選取ThreeJs作為我們3D渲染的底層庫去實現手機模型的3D渲染。

4.1.2 模型選型

瞭解了渲染庫,我們再來聊一聊常用的3D模型格式:OBJ、FBX、GLTF。

模型檔案其實是一個包含了頂點座標、索引(index)、UV、法線、節點關係、材質、貼圖、動畫等資訊的資料集合。不論模型格式如何,但是其本質就是對上述資訊的編排和組織。各種模型之間的區別無非是組織的方式不同,有些用純文字(OBJ),有些用json(GLTF),有些用二進位制(FBX)。

幾種不同模型檔案對比:

2D+1D | vivo官網Web 3D應用開發與實戰

2D+1D | vivo官網Web 3D應用開發與實戰

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自vivo官網前端團隊

透過對比我們發現幾種模型格式分別適用於不同的場景:

1) OBJ模型對於動畫的支援不是特別友好,而手機在做3D展示時需要進行一些模型的拆解動畫展示。

2) FBX 由於不同引擎解析的規範不同,導致不同引擎渲染出的效果差別較大

3) GLTF(GLB) 模型格式擴充套件性較高,ThreeJs、Babylonjs等WebGL渲染引擎的支援性較好

4.2 3D場景搭建及方案實施

我們發現,如果想要將3D場景中的物體展示的足夠逼真,相機和光照是必不可少的兩個基本要素。實際業務場景中還有模型顏色切換、模型旋轉、縮放、全景場景等邏輯需要我們去處理。

4.2.1 場景相機

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

4.2.1.1 正投影

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

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路()

正投影通常用在建築藍圖繪製和計算機輔助設計等平面圖形方面,這些行業要求投影后的物體尺寸及相互間的角度不變,以便施工或製造時物體比例大小正確。

4.2.1.2 透視投影

透視投影: 透視投影符合人們心理習慣,即離視點近的物體大,離視點遠的物體小,遠到極點即為消失,成為滅點。它的視景體類似於一個頂部和底部都被切除掉的稜椎,也就是稜臺。

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路(https://blog.csdn.net)

透視投影通常用於動畫、視覺模擬以及其它許多具有真實性反映的方面。相比較來講,透視投影則更接近我們的視覺感知。所以在官網的手機模型3D展示中,我們選擇透視投影來計算相機的投影矩陣。

4.2.2 場景光照

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

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

分別是 環境光(Ambient Light)、平行光(Directional Light)、點光源(Positional Light)。

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

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路(https://blog.csdn.net)

從圖中我們可以看出:

平行光是朝著某個方向照射的光,光線中的每一個光子與其它光子都是平行運動的。舉個例子,陽光就可以認為是平行光,平行光只能照亮物體的一部分表面。

平行光除了顏色外,同時具有方向屬性,屬於有向光。有向光和物體發生作用時根據物體的材質不同,會產生漫反射和鏡面反射兩種反射效果。3D場景中最終的反射效果是由環境光、平行光,漫反射以及鏡面反射疊加在一起的效果。

點光源是指光線是從一個點發射出來的,是向著四面八方發射的。這種光在我們的現實生活中是最常被用到的。舉個例子,電燈泡就是向各個方向發射光線的,它就可以被認作是點光源。

點光源不僅有方向屬性,還有位置屬性。因此計算點光源的光照,我們要先根據光源位置和物體表面相對位置來確定方向,然後再和平行光一樣,計算光的方向和物體表面法向的夾角。

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

4.2.3 模型旋轉實現

有了相機和光照就能夠比較逼真的將模型呈現給使用者了,但是還需要處理模型本身的一些互動操作,比如 模型旋轉、顏色切換等。實現3D場景中的模型旋轉有兩種實現方式:

(1)3D場景中的相機不動,旋轉3D實體即3D模型

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路

(2)旋轉相機,即3D模型不動,相機圍繞模型進行旋轉

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路

在現實生活中,將物體移動到視場中並不是正確的方法,因為在實際生活中通常是移動相機去拍攝建物體。所以我們選擇移動相機  即實現方式(1) 去實現3D實體的旋轉互動。

4.2.4 模型顏色切換

模型格式採用的是GLB模型(方便後期固化上傳),所以每一種顏色對應一個新的GLB檔案。

每一次切換模型需要重新對檔案進行解析,但是由於不同顏色模型間貼圖等材質可以共用,所以即使切換顏色時重新載入模型並解析也會比初始載入時的速度提升很多。所以考慮到後期的固化成本與複用性,切換顏色重新載入模型檔案,不失為一種相對比較優雅的處理方式。

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自vivo官網前端團隊

4.2.5 全景場景搭建

為了讓使用者在瀏覽產品的3D頁面時有更強的沉浸體驗。我們採用了全景模式。使用者在全景模式下旋轉縮放手機時,對應的背景元素同樣會跟隨相機的旋轉和縮放進行旋轉縮放。這樣使用者在進行瀏覽檢視時,互動的體驗感更強。

在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 = spherethis.stage.scene.add(this.bgMap)

上面程式碼首先建立一個球形幾何SphereGeometry,將建立後的球形幾何網格進行x軸反轉:sphereGeometry.scale(-1, 1, 1),使所有的麵點向內。然後載入圖片資料建立材質並加入map:new THREE.MeshBasicMaterial({map:texture});new THREE.Mesh(sphereGeometry, sphereMaterial) 最終實現全景圖效果。

4.3 效能最佳化

4.3.1 模型壓縮

為了提升頁面初始化的載入速度以及切換顏色模型時的解析速度,我們在製作完成模型後,需要對模型進行壓縮以降低模型的體積量。

谷歌針對GLB模型有一個壓縮庫 ,可以在不影響模型展示效果的情況下,對模型的體積進行壓縮。可以利用GLTF Pipeline命令列對GLTF模型進行壓縮。

壓縮的步驟:

1、安裝gltf-pipeline

npm install -g gltf-pipeline

2、轉換gltf至glb檔案

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

壓縮之後,glb檔案的體積會減少80%左右,所以在載入速度和效果呈現上會比原始的GLTF檔案更快。

2D+1D | vivo官網Web 3D應用開發與實戰

注:圖片來自網路

4.3.2 模型解壓縮

ThreeJs有針對壓縮模型的解壓縮方案:

// Instantiate a loaderconst loader = new GLTFLoader();// Optional: Provide a DRACOLoader instance to decode compressed mesh dataconst dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( '/examples/js/libs/draco/' );
loader.setDRACOLoader( dracoLoader );

首先構建一個GLTFLoader物件,然後在進行模型載入過程中,設定dracoLoader解析檔案的路徑,dracoLoader對壓縮後的模型檔案進行解析。最後將解析後的檔案返回至指令碼進行渲染呈現。

五、總結

本篇文章首先介紹了2D資料視覺化,透過將平面圖表資料視覺化形式拉伸到三維立體結構,衍生出了3D資料視覺化相關內容,以及官網基於ThreeJs的3D應用開發實戰。

但是WebGL關於3D渲染相關的知識遠不止這些。這裡只是列舉出了比較常用的幾種3D模型的渲染要素,比如燈光,相機等。實際還有關於物體材質的光的反射型別:漫反射、鏡面反射,相機也有其他型別的相機模型:例如:正交相機、立方相機、立體相機等,由於篇幅原因我們不再做詳細的介紹,感興趣的同學可以去 WebGL官網去檢視並學習相關內容。


作者:vivo 官網商城前端團隊-Ni Huaifa


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69912579/viewspace-2767407/,如需轉載,請註明出處,否則將追究法律責任。

相關文章