網頁即時 3D 渲染的深度修行


杉悟互動 ─ 融合藝術、設計與數位技術的設計公司
為品牌打造絕佳的數位體驗。


在專案初期的技術評估,我們參考了大量的捏臉遊戲(#虛擬替身、#紙娃娃), ACRZ:AlphaCrewzZEPETOBondee、以閃亮之名等,從上述案例可以看到,都是以 Unity 甚至是 UE4 這類遊戲引擎開發,又或者平台類的 Memoji、instagram 虛擬替身,以網頁製作的案例真的非常少,在大家的眼睛已經被各種遊戲寵壞的今日,杉悟要如何用網頁技術做出比擬遊戲品質的捏臉遊戲呢?

👨🏻 老闆:明天開始大家去學化妝
👱🏻‍♀️ PM:👌
👩🏻 設計師:👌👌
👧🏻 3D:👌👌👌
👦🏻 工程師:️🤷🏻‍♂️🤷🏻‍♂️🤷🏻‍♂️

✴︎ 先看成果,以上皆為網頁渲染的最終效果

為了順暢的跨域協作,專案初期整個團隊開了一場 8 個多小時的會,集結 PM、視覺設計師、彩妝師、3D 設計師、工程師等⋯會議上從時程、美術風格,製作規格,檔案交付方式,通盤的過了一遍,雖然並不是因為有了這場會之後就完全沒有意外,但絕對為整個專案定下了良好的規範。

由於此次前端的 3D 庫是使用 Three.js,所以下面提到的功能,以及備註主要都會以 Three.js 的功能來說明



✴︎ 要呈現這麼多造型,模型檔如何切分?

這是專案初期的一大難題,看似只是一個檔案切分與交付的問題,但實際影響非常廣,從基本的如何分工/檔案交付,到模型貼圖如何切分,甚至是模型的載入時機與切換時機,算是一個牽一髮動全身的問題。

而頭像是整個模型的核心,由於組合太多又沒有很好的切分點,在多方評估後,決定將所有五官、臉型包在一個模型內,以改變骨架的方式,來控制不同的五官,這大大的降低了模型載入的量,也讓五官改變的過程非常順暢,只需要付出很少的檔案容量,就可以增加組合。

看似對開發與效能都友善的作法卻異常考驗 3D 設計師的能力,因為要用一組骨架控制所有五官,例如從小眼睛 → 大眼睛,或者從下垂眼 → 丹鳳眼,又加上彩妝會被放大檢視的狀況下,對權重以及 UV 的掌控要求極高,來回調整了非常多次骨架結構與權重,才克服了變形的問題。

 

更換五官的實作流程

  1. 設計師將所有五官在模型檔都按照順序放在時間軸上,且為了方便管理,不論哪個部位,都是從時間軸的 0 開始,所以出現左下影片中不同部位一起變化
  2. 工程師載入模型後,讀取模型的完整骨架數據
  3. 從動態資料中整理出有改變的骨頭
    對照 歸零數據 與 變形數據,區分每個骨架的影響範圍
  4. 撰寫程式邏輯,最後依照使用者選擇,讓骨架套用對應的數據
    ( 可參考下面影片 )

在這類的捏臉遊戲中,自由度與還原度是一大功課,數量絕對是撐起精彩程度的關鍵之一,但在時程有限的情況下,我們只能取最大公因數,盡量以常見/流行/共鳴高的造型優先,這次的成果約可搭配出 10³² 種組合,即使移除所有顏色的選項,還是能有約 1.05 * 10¹⁹ 種組合,有朋友一玩就不小心玩了 2 小時,女孩們真的是會欲罷不能

工程師特別寫了亂數搭配,以及循環轉動來錄影 💫

✴︎ 關於渲染的細節

在網頁中即時渲染 3D 內容最困難的就是在沒有 光線追蹤 ( ray tracing ) 的功能下,如何渲染出模型的細節與層次?

通常是使用 “烘焙” 這個技巧,烘焙是透過 3D 軟體,預先將光線追蹤後的效果渲染好,並印在貼圖上,使這些效果不需要 “即時運算” 就能有相同的效果,但既然是預先算好,當模型、或光線改變時,就會出現破綻,所以在此次有高頻率模型切換的情況下,就不能過度依賴烘焙,下面我們會以 3 個面向,不藏私的分享我們在渲染優化時,細節中的細節!

︎⁽ ¹ ⁾ 彩妝實作

彩妝的部分是運用呈現 3D 模型色彩的 diffuse map 來製作,且因為這張貼圖要支持局部更換,所以我們將每個部位拆開,最底下墊了烘焙好的皮膚質感,再依照使用者選定的項目即時合成在一張 canvasTexture,合成完之後再更新至人臉的材質上,切換妝容的過程好療癒~真的非常有從素顏到完妝的既視感!

而這部分與開頭提到的檔案切分問題非常呼應,由於整個臉的模型是共用的,因此不論五官如何切換,在 UV 的作用下彩妝的貼圖只需要一套!並不需要因應不同五官組合而分開製作,前面花時間來回調整共用模型的投資此時顯得非常值得!關於彩妝的實作,我們也整理了製作時須考量的延伸問題

  1. 每個區域的貼圖要多大張,才能兼顧品質與效能
  2. 以程式合成貼圖時的順序?
  3. 貼圖合成時是否有需要混合模式 blend mode
  4. 這麼多的素材要以程式來合成,如何準確還原
  5. 光彩妝的貼圖約 2700 多張,大量素材最佳化流程

上面這些問題都蠻看專案的實際情況,除了素材最佳化這題,下次來寫杉悟壓縮與優化的流程好了,敬請期待!

⁽ ² ⁾ 白裡透紅的皮膚質感

要呈現皮膚白裡透紅的效果時,標準做法是使用 次表面散射 Subsurface scattering,簡稱 SSS,這是一個運算物品透光的算法,但由於要盡可能的減少即時運算量,我們最終選擇使用 emissive 來實現這個效果,算是有點 hack 的做法 😅

SSS 與 emissive 兩者的差異是前者用來表現物品被光穿透(例如將手機上的手電筒打開,再用手指按住手電筒的燈光);而後者是表現物品自體發光。

兩個功能的本質是用來呈現完全不一樣的效果,但也是因為都與光有關係,只要使用得宜,效果非常接近,且 emissvie 搭配 emissive map 可以非常彈性的控制發亮範圍與強度,甚至是漸層式的發光,小缺點是 emissive 需要為每一種膚色去搭配適當的顏色與強度,且它會影響到物體本身的顏色,對色彩呈現要絕對準確的情況下要謹慎使用。

 

 

⁽ ³ ⁾ 打光細節

打光在 3D 渲染中的重要程度就與拍電影或實際攝影時的燈光一樣重要,好的燈光師不但讓你五官更立體,還能營造各種美妙的氛圍,反之則可能功虧一簣!下面直接用影片解析我們的打光過程

  1. 無燈光。
  2. 選擇 HDRI,鋪墊整體調性。
  3. 依照 HDRI 的環境光源,以 spot light 打一盞主燈,陰影也是由這盞主燈來投射。
  4. 在受光面補一盞 point light,會選擇 point light 是因為這個光型在明暗的過程滑順,比較不會在臉上留下銳利的光影分界線。
  5. 在陰影面也補一盞 point light,這盞燈要比受光面的弱,維持 Step 2. 的主調。
  6. 這次的燈光概念以柔和且清晰明亮為主,所以用 ambient light 微調整體亮度,同時以這盞燈微調整個環境的色溫。
  7. 以 spot light 打一盞背燈,用高光勾勒出輪廓。
  8. 此次專案最有趣的燈光用法,hemisphere light 半球光是將一個球型光切一半,上下半球分別可以定義一個顏色,以此來模擬戶外環境,頭頂藍天與腳下土地反射的不同色溫,若我們將上半部設為黑色,藉此就可以設定下半球來獨立微調陰暗面的色溫,這次我們加了一點點的紫藍色,讓原本整體棕色調的光影更有時尚氛圍。
  9. 在燈光完成後,微調上一段說到的 emissive,讓整體更和諧就完成了!

看以上說明是不是很簡單呢~

但實際上我們的設計師需要先研究網頁環境的燈光效果,並且每次調整時需要來回調整燈光與貼圖,當時設計師可是花了好幾天,嘗試了 20 多種組合反覆調整,最終才定下這組令人滿意的成果!

✴︎ 效能優化

為了展現設計品質,渲染一個完整的 avatar 模型會使用到 9 ~ 14 萬個三角面(依用戶選擇的項目有所不同),以遊戲且模型集中在上半身來說,面數是偏高的,且因為組合變化實在太多,所以陰影也須即時運算,在這樣重度的運算中如何確保順利運行,以下就來分享我們優化效能的方式!

 

︎⁽ ¹ ⁾ 限制渲染時機與幀數

即時渲染中最耗效能的就是這句( 以 threejs 為例)

renderer.render( scene, camera );

所以我們非常謹慎的控管渲染時機,限制只在換妝時,且在模型、妝容貼圖都載入完成後才重新渲染畫面。並且當轉動攝影機時的更新,也將渲染頻率限制在 20 fps,這樣的更新頻率對絕大部分的人眼已經足夠順暢。

雖然也可以讓網頁跑滿 60 fps,但限制在 20 fps 的做法可以有效的讓手機發熱的時間延後甚至不發生,且包容更多的舊手機可以順暢使用。

 

⁽ ² ⁾ 限制事件觸發頻率

若使用者瘋狂點擊換妝還是會讓畫面更新頻率提高。因此當使用者點擊換妝後,程式設定有個 800 毫秒的 delay(若已有計時器就重新計時),計時器結束後才會依使用者選擇的最後一個選項更新畫面,以此避免使用者快速點擊造成的負載過度。

 

⁽ ³ ⁾ 回收機制

在以往專案進行 2D 或 3D 的繪圖時,物件少的情況下不太需要回收。但這次專案素材總共有上千個,一次體驗平均只有一百多個會被選過,其中會在畫面被同時渲染的大約十多個。

每當使用者更換了新造型後,原本的造型就會被閒置,而這些暫時用不到的素材( model/material/texture… )存在記憶體中並慢慢累積後容易導致網頁崩潰。

因此在每次換掉造型後,特別將這些素材從記憶體中釋放(dispose),儘管後續當使用者選到被刪除的素材需要重新載入,但這樣犧牲載入速度換取網頁正常運作,是我們覺得較為平衡的做法。


✴︎ 意外與排除

這次我們的工作流程概略為 3D 內容在 Blender 製作,並以 Threejs 官方的 Editor 來模擬在網頁中的狀態,確認無誤再出檔案給工程師,但在製作期間我們遭遇當時的 Threejs Editor 上傳貼圖時會有 bug ,但所幸 Threejs 與 Editor 都是 open source,於是工程師將官方的 Editor clone 後修復了 bug 給設計師使用,真是太帥了。

但禍不單行,後來又發現 Editor 的渲染結果和真正的網頁環境不管如何調整都會有一點點落差,考量到美術設定若有更新,程式與 Editor 都要再更新一次實在管理不易,因此工程師乾脆製作了可以上傳妝容貼圖的網頁環境,讓設計師可以即時確認妝容效果是否符合預期,設計師讚嘆阿!


✴︎ 上線與後記

走完了這趟深度修行後,我們對於這類 3D 網頁的製作有了更深刻的體悟,看到最終成品的品質,團隊每個人都充滿成就感!

過程中非常感謝客戶的支持,客戶與我們一樣非常喜歡此次的專案!網站成效也是令我們驚喜的一部分,在主要的 15 天推廣期內,累積了 289 萬次的 avatar 樣貌編輯次數,平均每位使用者點擊了 160 次,平均停留時間高達約 5 分半,這真的是對於專案最大的肯定 ❤ 

💄 說了這麼多,歡迎大家直接到線上體驗這次的 shu avatar

最後來看一段我們為這次專案做的分享影片

這次的專案先分享到這,如果你對這樣的內容有興趣,歡迎到各個平台追蹤我們,我們會不定期分享各種專案裡的乾貨!

同時杉悟也持續尋找各領域夥伴,舉凡設計、3D、網頁前後端甚至 AI 應用,各種合作可能歡迎來信 hi@salute-interactive.com


杉悟互動 ─ 融合藝術、設計與數位技術的設計公司
為品牌打造絕佳的數位體驗。

Instagram ⇀ https://lihi1.me/TXPMk
Behance ⇀ https://lihi1.me/kQCu3
Website ⇀ https://lihi1.com/iZDaR


Related posts