如何用 Cocos Creator 3D 如何实现小姐姐的发丝高光?
Introduction
PRB 材質改變了人們對于引擎實時渲染畫面的理解,讓玩家在游戲中,也能夠體驗到銹蝕的金屬,厚重的皮革,精細的紋理,感受更加真實的世界。在正式發布的 Cocos Creator 3D 中,真實感渲染和強大的材質系統成為開發者關注的一大重點。為了給 Web 和小游戲平臺帶來更好的 3D 游戲表現,Cocos Creator 3D 首次真正將基于物理渲染全面帶到了小游戲中,不僅支持 PBR 材質,還將光源系統和渲染統一升級為基于物理的度量衡和算法。
在 2019 年 9 月份深圳技術分享會上,Cocos 3D 引擎開發工程師武云瀟,為與會開發者帶來了?Cocos Creator 3D?材質系統的分享,內容由淺及深,實機演示 3D 材質系統的工作流,并準備了具體的案例學習環節。
?
以下內容是演講干貨整理:
?
Definition
要了解材質系統,首先需要知道什么是材質。
要知道什么是材質,首先需要明確什么不是材質。
下面我以頭盔場景作為案例,為大家展示講解。
?
對于這個頭盔而言,材質系統到底在其中發揮了什么作用呢?
為了更直觀地說明,我們不妨把所有材質系統的貢獻全部剔除,看看還會剩下什么。
?
可以觀察到,除了頭盔的形狀,所有的表面細節、對光照的反饋、顏色質感等信息都消失了。這些信息決定著一個幾何體的材質,也是材質系統控制和提供定制化的最重要的內容。而幾何體的形狀本身,是由模型數據決定的,如果我們把這部分最原始的數據可視化出來,可以看到,這一個個分散的三角形,才是游戲世界中所有模型的本來面貌。
如果把渲染看做畫畫,材質系統最重要也是最基礎的功能,就是在已有線稿的基礎上,控制如何給這里的每個三角形上色。(當然更進階的,也可以控制線稿本身的一些細節,甚至處理更為復雜的計算任務,如骨骼動畫的蒙皮等)
Presentation
現在我們對課題有了基本的定義,就讓我們來利用引擎內置的材質系統,一層層把顏色上回去,以熟悉一些基本的工作流。頭盔模型使用的是標準材質,背后是目前業界普遍使用的基于物理的渲染模型(PBR),是一套很好地權衡了高效和美觀的算法。
?
當算法框架足夠合理時,視覺上的“美觀”很大程度上就取決于“信息量”了,這個模型本身是專門為展示 PBR 各個層級特性而制作的,可以看到,隨著每一層貼圖信息的加入,它們共同融合成了一套統一和諧的效果。
當然材質系統的任務是提供方便的定制化,所以并不和某套渲染模型掛鉤,在同樣的系統下,我們可以很方便地提供比如卡通渲染的支持。
?
?
(致謝:卡渲框架設計受 UTS2 啟發)
Deconstruction
這里要提一下,材質系統是 Cocos 針對 Creator 3D 架構設計的,但目前 Creator 2D 從 2.1.1 版本開始同步引入了材質系統,已在使用其中大部分的前端設計,并針對渲染后端做了適配和優化,所以今天分享的內容對兩款產品均適用。
首先既然定位是小而精,那么需要明確,我們希望做到的,和我們沒有打算做到的(至少現階段而言)
我們希望做到:
?
- 對 TA:全自動處理書寫 shader 過程中瑣碎易錯細節的趁手有力的工具
- 對 TA:任何內容與算法都應不受阻礙地完成
- 對美術:以最便利、符合直覺的方法接收 TA 的產出,無縫連接下一步的創作
現階段不打算做到:
?
- 工業級別的 shader 語言轉譯/優化器
- 使零程序基礎的美術也能加入 shader 創作流程
我們希望在 TA 和美術各司其職,各自發揮優勢的過程中,引擎和編輯器能夠首先成為雙方合作的堅實基礎和便利橋梁。最終設計也是這點的直接映射,一個非常小巧高效的系統,各自有著明確的目標和能力:
?
- EffectAsset 是由 TA 或圖形程序設計制作,提供定制化的著色機制和數據接口
- Material 是由美術創建,會被大量用在實際游戲場景中的資源實例,負責提供所有實際使用的數據
- 所有 EffectAsset 層提供出的接口都會以最自然便利的方式在 Material 面板上呈現
這里舉兩個小細節,更多信息及接口文檔參考 [3]
?
- Shader 中所有 uniform 變量聲明都會在資源導入時解析依賴宏,并直接映射到編輯器的材質 Inspector 上
?
- TA 只需要按照標準 GLSL 語法完成目標邏輯,大部分繁瑣易錯的膠水代碼可以全部通過固定解析流程自動對接。
- 對于需要自定義這個過程的需求,有完善的 uniform 重定向,及類似 ccclass 的定制系統 [5]
?
比如這里紅框內的四個屬性,在 Shader 中其實是同一個 vec4 的不同分量(參考 [4] 關于 UBO 成員布局的考慮,為了達到最佳性能確實會出現類似需求),但為了使用起來更符合直覺和便于調整,在 Effect 中為每個分量單獨增加了新的屬性,使得它們可以被獨立編輯,無論是在 Inspector 還是代碼中直接調用。
現在我們清楚了材質使用層面的設計,讓我們繼續深入底層,來看看在 Effect 層面我們有哪些實用的設計。這是一份標準的 Cocos Effect 文件示例(也是引擎內置天空盒使用的 Effect):
?
在聲明式語法的大框架下,賣游戲賬號平臺已經可以看出一些有趣且實用的選擇,它的主要特性有:
- 統一的 Shader 語法(GLSL 300 ES)
- 多 Technique 多 Pass 支持
- 標準頭文件庫、Include 機制
- 常規語法自動 Fallback GLSL 100
- 進階語法通過 __VERSION__ 宏手動 Fallback
- 大量引擎、渲染管線、運行平臺相關的類型檢查
- 定制化 Inspector 對接集成
這背后是一直在不斷完善的 Cocos Effect 語法和編譯器,從設計之初理念就忠于 C 語言設計哲學,我們致力于提供一套明確清晰的 Shader 書寫工具集,使得每一個細節的控制都是透明可見/可推導的。更多 Effect 相關具體特性這里不再詳細解析,可移步參考官方文檔 [4]。
Demonstration
恭喜大家堅持到了現在,我們終于要進入今天的案例環節了。今天的案例是頭發高光的計算。無論在現實生活還是各類動漫游戲作品中,頭發高光都是頭發不可或缺的一項標志特性,也非常討人喜愛。
?
那么如何在游戲項目中實時計算這樣的高光呢?
我們先來嘗試簡化問題,這里是一個使用標準卡通渲染的球體(下圖),它的高光是按標準 Blinn-Phong 模型計算的,可以看到只在光源的理想反射方向可見,就是一個圓點。
?
但如果我們把這個球體近似地看成角色頭發的話(如上圖右下角示意),其中最顯著的特征是,我們希望這個高光不是一個圓點,而是……一個圈。我們今天案例解析的重點,就是如何從物理上理解,并實時近似計算這個高光圈。參考學界的一些相關論文,這個問題的基本思路是把每根發絲近似地看成是一個個很小的半透明圓柱體,而可以證明 [1],在理想圓柱體上,對平行光而言,它的所有出射光線都在一個和理想反射方向傾角相同的圓錐上(如下圖中間示意)
?
我們看到的頭發上連成一圈的高光,就是因為這個特性而產生的。(聯系下現實生活的話,其實是發質越好發絲越接近圓柱體,所以高光越明顯)。所以有了基本的模型,我們來擴展一下基本的 Blinn-Phong 高光計算,讓它從單一方向變成到整個圓錐,就應該能在這個球體上看到變化。可以很快發現,這個圓錐中軸與發絲方向平行,圓錐大小只是由一個與發絲方向的夾角決定的,那如何取這個夾角呢?這樣的需求,一般會使用模型的切空間數據來輔助計算,我們先來看一下這個球體的切空間數據。
?
這里做了切空間數據的可視化,圖中球體上黃色線段就是每個頂點的副切線,可以看出也是我們需要的“發絲方向”。當然對于更一般的頭發模型來說,這個方法會對模型的 uv 展開方式有要求,要求頭發部分的 uv 縱軸應當與發絲方向基本一致;不過好在這種展開方式相對普遍,制作美術資源時也經常這樣做,所以適用性還是較為普遍的。
?
我們在 shader 中可以很方便地把每個片段計算 BRDF 常用的向量(R、V、N、H、L)和副切線 (T) 取到,根據論文 [2] 中的思路,這里我們也直接用一個 gaussian 來做近似,那么可以基于 Phong 著色模型,寫一個最符合直覺、易于理解的版本:
?
其中 mr 就是通過 gaussian 算出的連續的高光亮度,通過一個 step 函數切出卡渲效果的硬邊。在此基礎上可以進一步嘗試優化為 Blinn-Phong,寫出來要比想象中更高效一些:
?
這里 3 和 6 其實都是用戶可調參數,為了對接原有卡渲參數這里調整合適后硬編碼進來,最后運行效果是這樣:
?
?
這樣我們就有了一個適用于發絲的卡渲 shader 了,調整一下還可以控制高光寬度和位移(想一想位移參數應該怎么加)。如果從背光面觀察可以看到還是有一部分不太真實的反射,這是因為我們沒有考慮方位角維度上的反射強度差異。并且像圖中所示那樣,我們其實只非常粗略地計算了完整發絲高光模型的主高光,即反射部分,還有更多的散射項沒有考慮。這里不再深入介紹,感興趣的同學,推薦閱讀下面兩篇參考論文 [1]、[2] 深入了解,并嘗試自己實現更真實完整高光的效果。
總結
以上是生活随笔為你收集整理的如何用 Cocos Creator 3D 如何实现小姐姐的发丝高光?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全境封锁UI游戏设计指南
- 下一篇: 腾讯云为小游戏开发者升级工具箱 小游戏联