這是侑虎科技第226篇原創文章,感謝作者張言豐(資深TA,QQ:306566807)供稿。當然,如果您有任何獨到的見解或者發現也歡迎聯繫我們,一起探討。(QQ群:465082844)
筆者去年寫了一篇關於如何打造高逼格耀斑效果的文章,很榮幸得到大家的關注。本人平日樂於分享自己工作中的點滴技術心得,歡迎大家聯繫我進行技術相關的交流學習。
今年筆者在PintaStudio,這是我在中科院的同學創立的一家VR電影工作室,我們希望用遊戲引擎實時渲染的方式來表達藝術家的思想。同時,我們製作的VR沉浸式感受也是一種全新的觀影體驗。接下來,我將簡述整個開發的歷程。
VR交互動畫短片《拾夢老人》劇照
◆◆◆◆引擎的選擇(Unity VS UE)
立項階段,我們遇到了引擎選擇上的分歧。我們想做的是重量級大作,所以最初的想法是採用一個重量級引擎。早期做端遊時,我們了解得最多的是CRY ENGINE(下稱「CE」)和UNREAL ENGINE(下稱「UE」)了,這兩個引擎就是引擎界的「西門吹雪」和「葉孤城」,長期霸佔著國外的大作市場。CE這些年在國內推廣不利,所以在最初階段,更多的小夥伴希望用UE來做我們這個電影。我的加入,給團隊帶來了新的選擇—Unity。相比前兩個引擎,Unity可以說是後起之秀,尤其近3年手遊的興起,才把Unity引入大眾的視線。我們主要對UE和Unity兩個引擎進行了比較:
綜上所述,我建議團隊採用Unity引擎。儘管後來被幾個大坑坑得鼻青臉腫,但是從項目進度以及結果來看,這個引擎基本上達到了我們想要的效果。
◆◆◆◆技術創新
Unity引擎本身的畫質相對來說是較為簡樸的,但是對於電影來說,藝術家希望能有一些更豐富的畫面表現。我之前在公司運營團隊寫的一篇文章裡也簡單提過,大家可以參考:
http://www.vrzy.com/vr/60852.html
在這裡我們舉個簡單小例子:
如上圖這個光影效果,上面窗戶衍射效果就有很多種實現方法。先對Depthmap做邊緣的blur,然後計算光照是一種辦法;直接對Render Target做局部的bloom也是一種方法;OffScreenRenderTarget,渲染一張低解析度的光照貼圖,然後合成回MainTarget,也不失為一種好方法。
對於地上陰影的邊緣效果,怎麼實現呢?CookieTexture?錯誤,你沒有辦法用CookeTexture去解決不規則的陰影衍射,更何況陰影的邊緣顏色是藝術家幻想的。那怎麼辦?其實不難,它是軟陰影算法的變種,所以,利用概率採樣ShadowMap的方法得到陰影邊緣,然後在邊緣地區做顏色疊加即可實現。
我們再舉一個小例子:
這狗的耳朵是不是有點透明?其實這就是個SSS效果,實現方法是:對於一個表面,沿著視線方向做一個延伸,取到次表面的光照,再疊加到前表面的顏色上。仔細看Unity樹葉的Shader(Unity內置Terrain裡的Shader),有個變量backcontrib,是把樹葉背面的顏色疊到前面來,其實也是sss的變種。
◆◆◆◆
重重阻礙
我們項目的開發進程充滿艱辛,在此列舉部分,給可能要入坑的同學提個醒:
1. 普通物件Standard材質
因為進度原因,我們仍然採用了Unity自帶Standard裡的PBR光照模型,這個光照模型是經典模型的簡化版,對於大多數渲染對象來說還是可行的。但Unity自帶的StandardShader在支持半透物件時,就會出現癱瘓的情況。如下圖:
左圖為正確效果,右圖為UnityStandard的錯誤效果。這是由於StandardShader裡Transparent 沒有 Z Buffer 導致。那麼有同學又會問「我用cut out不就行了麼?」但是cut out是用RenderQueue來解決問題的,我希望上面這個腿和靴子來個半透明效果,它就沒辦法實現了。比如下圖這個淡出效果:
此外,Unity還有一個致命的「優化」,就是在OpaqueQueue之後會把ShadowMap給銷毀掉。所以半透明物件無法接受陰影。另外,關於點光源,如果光源範圍內沒有任何物體,Unity會把Lightmap也「優化」掉。類似這樣的小細節Bug比較多,但需求不會因為引擎的Bug而減少或者降低標準。一個坑一個坑地填起來,也花費了我們相當大的精力。
2. 特效
如果說普通物件的材質是被Unity坑了一下,那麼特效就是被VR的SDK給坑得鼻青臉腫。當時我們用的是HTC VIVE的Steam VR的SDK。研發完成之後才發現,這個SDK對RenderCommand和OffScreenCamera支持極差(OffScreenCamera沒有辦法左右眼矯正),也就是說所有的特效必須寫在固定管線裡,比如這種Volumetric Light。我們需要離線烘焙好ShadowMap,然後再前向渲染時,用RayTrace去模擬它的attention。
上面兩張圖中,左圖是正確的效果,右圖是SteamVR裡可能看到的效果(因為OffScreen Camera位置沒有經過左右眼矯正,所以位置看上去是偏移的,甚至不在屏幕裡)。
3. 其他
在VR的開發中,相機也是個坑。因為傳感器會實時地重置相機位置,所以你沒有辦法去動態改變相機,只能通過反向移動場景的方式來實現相機的動態切換。這也消耗了我們很多的時間來填這個坑。
◆◆◆◆展望
Unity 引擎自帶的渲染模塊基本都有些許欠缺,但是近年來隨著Compute Shader、Render Command這些接口的提出,給我們引擎開發者提供了很大的可擴展空間。正如我多次在UWA技術群(465082844)裡呼籲的:引擎是用來幫助開發者減少工作量的,不是用來完全依靠的。沒有一款引擎能滿足所有項目都通用的需求,所有引擎都需要根據不同的項目來做修改。一個不會造發動機的人,可以開車,甚至簡單地維修汽車,但是你沒法成為造車場的老司機或者職業賽車手。
附《拾夢老人》1分鐘唯美預告片:
文末,再次感謝張言豐的分享,如果您有任何獨到的見解或者發現也歡迎聯繫我們,一起探討。(QQ群:465082844)。
也歡迎大家來積極參與U Sparkle開發者計劃,簡稱"US",代表你和我,代表UWA和開發者在一起!
_周五活動:UWA 技術診斷一對一!
近期精彩回顧
【UWA DAY 2017 精彩盤點】沒有橫空出世,只有厚積薄發!
【萬象更新】限時免費 | 用正確的方式,三天搞定Mono堆內存洩漏!
【惟學無際】基於物理的渲染-用真實的環境光照亮物體
【U Sparkle】GPU Skinning 加速骨骼動畫