1. 程式人生 > >Unite 2018 | 《崩壞3》:在Unity中實現高品質的卡通渲染

Unite 2018 | 《崩壞3》:在Unity中實現高品質的卡通渲染

width diffuse 動態生成 LG 編輯 www. tgs term 謝謝

本篇文章為Unity官方論壇發布的文章 由於全是幹貨,為了方便自己查找,也為了避免刪除找不到了 於是復制了過來。。。 原文地址: http://forum.china.unity3d.com/thread-32271-1-1.html http://forum.china.unity3d.com/thread-32273-1-1.html <ignore_js_op>技術分享圖片



下面為演講內容:

大家好,歡迎來到Unite2018參加我們這次演講。簡單做一下自我介紹,我叫賀甲,目前在米哈遊擔任技術總監。我和我的團隊主要關註在PBR和NPR方面的實時渲染,以及用於動畫CG和遊戲的過程動畫和交互式物理的研究。目前,我們的一部分工作是利用Unity實現高品質的卡通渲染。

這次演講的主題是《在Unity上實現高品質卡通渲染的效果》,這些方法的實現針對各個平臺的特性進行了優化,涵蓋了從移動端,到高性能PC等不同等級的平臺。

<ignore_js_op>技術分享圖片



我們先來簡要介紹一下本次演講涉及到的主要方面。首先會介紹一些應用在移動端有關《崩壞3》的渲染特性。然後我會談談動畫風格CG渲染中使用的一些技術,例如:插畫風格的角色渲染、特殊材質的渲染、特效的渲染及與卡通渲染適配的後期處理等。最後一部分是關於一些雜項和對今後實現的一些展望。

<ignore_js_op>技術分享圖片



首先,我們來看看在《崩壞3》的場景中使用的一些渲染特性。

從下圖中我們可以看出,場景中使用了不少特效來提升表現力。例如:bloom後處理效果、動態粒子、平面反射、屏幕扭曲特效等。下面我們將會逐一對這些效果進行解析。

<ignore_js_op>技術分享圖片



下面展示了這些動態特效。

<ignore_js_op>技術分享圖片



我們來看一下如何實現高品質的反射效果。

在移動端實現高品質的反射,平面反射是一個綜合了效果和性能因素較好的辦法。通常做法是以地面為對稱平面,將攝像機放置在對稱位置後渲染場景得到反射結果。

為了能表現出地面的金屬質感,首先我們對反射結果應用六邊形采樣模糊,然後使用金屬紋理細節法線貼圖來擾動反射結果,除此之外我們還使用了鏡面反射貼圖和菲涅爾效果來進一步增強反射質感。在一些遠離地面高度或非水平的次要反射表面上,平面反射就不在適用,為此我們使用環境貼圖反射作為替代方案。

為了盡量減少渲染反射場景所占用的開銷,我們將反射分辨率限制在1/3以下,由於反射貼圖會經過模糊處理, 即使降低了較多的分辨率也並不能明顯看出區別,並且我們在渲染反射的過程中還使用簡化版的材質,並忽略一些不是很重要的小物體。

<ignore_js_op>技術分享圖片



接下來讓我們看看另一個效果:全屏扭曲特效的應用。

我們在《崩壞3》的場景中較多的使用了屏幕扭曲效果,比如:刀劍的拖尾特效,時空斷裂效果,水流瀑布及其它場景效果。

在渲染扭曲效果的過程中,我們使用3個通道來存儲扭曲的渲染結果,2個用於存儲UV偏移,另一個用於存儲扭曲強度Mask,扭曲強度Mask用於執行深度剪裁和基於距離的強度控制。

使用單獨的Pass渲染扭曲結果到幀緩沖紋理對於移動平臺來說開銷較大,所以我們在最終的後處理中整合應用了扭曲效果,相比前者要快很多。 但這種方法也可能導致靠前面的物體由於沒有分層處理而混入後面扭曲材質的問題,不過考慮到移動平臺的性能限制,相對於整體效果而言這種妥協是值得的。

<ignore_js_op>技術分享圖片



接下來讓我們看看bloom的實現,整個場景如果開啟HDR會使用 fp16格式的Render target,然後下采樣到原始大小的1/4大小以便之後的後處理流程使用。

首先,我們需要指定一個亮度閾值來提取圖像中的高亮區域,實現方法也並不復雜,只需從源像素減去閾值,得到的結構就是提取後的高亮度區域,疊加這層內容能使結果看起來更具對比並且色彩鮮艷。接下來,我們產生4個大小依次遞半的Render target,並將其內容應用半徑逐漸增大的高斯模糊。最後我們將這些模糊後的結果合並起來,以獲得最終的bloom效果。

從下面最終的效果圖我們可以看到,bloom效果不僅起到用來表達高亮區域的視覺效果,還對整個圖像的色彩中起著明顯的潤色作用。

<ignore_js_op>技術分享圖片



當完成了反射渲染,扭曲效果的及bloom 的處理後,最終就可以將這些中間結果合成在一起。我們使用filmic tone mapping與曝光和對比度控制來將fp16 HDR的原圖像轉換為最終的LDR幀緩沖。由於這些合成操作都是在一個Pass中完成的,所以即使在移動設備上也可以滿足性能方面的需求。

<ignore_js_op>技術分享圖片



下面我們來介紹一下遊戲中的天氣和雲海的實現。

我們想要創造一個能讓玩家感受到縱深,具有各種豐富形態以及動態光照變化的雲的渲染系統。而該系統也應該易於調整和使用,方便美術可以創造出不同類型的雲層效果。這對我們來說也是一個有趣的挑戰,接下來就讓我們來談談這些功能。

<ignore_js_op>技術分享圖片



首先讓我們看看渲染雲所需要的資源,因為我們想要實現可以24小時動態變化的風格化雲的光照效果,如果直接存儲畫好的貼圖數量就會太大而且不方便調整,所以我們使用多層著色來實現這一點。

我們使用4個通道來表示雲的光照及陰影:基礎照明層,陰影1層,陰影2層,和邊緣光層,通過為每個圖層設置不同的顏色,我們就可以獲得不同時刻的雲的色彩方案。我們一共準備了8種形狀不同的雲的模板,用來構建各種不同的雲海景觀。

<ignore_js_op>技術分享圖片



為了構建雲海景觀,我們使用了很多朝向屏幕發射雲朵的粒子發射器,並且使用不同的雲的模板以及發射模式來組合出不同的雲海景觀,我們實現了各種類型的雲海以及暴風雨天氣等,這些預設都保存在天氣配置中。此外我們還使用關鍵幀來定義天空背景和雲彩的顏色。隨著時間的流逝,雲的色彩就根據關鍵幀來變化。

在性能方面主要的開銷是Overdraw問題,如果我們按照固定控制的Pattern來發射雲雖然可以以最小的Overdraw來獲得較好的雲海密度,但可能會看起來較為重復,加入產生位置的隨機因素可以解決這個問題,但要想獲得看起來不那麽稀疏的雲海效果就需要相比固定Pattern更多的粒子數量,我們對於粒子發射配置都有細致的參數可以調整,以便在二者之間可以找到較好的權衡點。

<ignore_js_op>技術分享圖片



這是一個24小時晝夜變化的雲海景觀。

<ignore_js_op>技術分享圖片



這是另一種雲海景觀的晝夜變化。

<ignore_js_op>技術分享圖片



這是暴風雲閃電的場景。

<ignore_js_op>技術分享圖片



現在讓我們來看看遊戲場景中使用的天氣系統。

我們主要通過全局霧效,Skybox顏色和方向光的設置來改變場景的天氣和氛圍。對於霧效同樣有許多參數可以調整。我們給霧效基於深度劃分為遠近距離二個區間,遠近區間都可以設置不同的顏色和強度值來創造各種各樣的氣氛。Skybox也可以控制天空顏色漸變,雲的受光及陰影顏色等。綜合上述調整選項,我們就可以創建 晴天,雨天和大霧,多雲和夜間等天氣。

另外人物的光照也會受環境的影響,主要的光照顏色由方向光決定,局部區的陰影的變化,比如:角色走進陰影區域,由一些從關卡編輯器中手工放置的Lighting volume定義。

<ignore_js_op>技術分享圖片



讓我們再來看看遊戲中使用景深的情況。

移動遊戲中使用景深一般並不常見,因為常見的景深實現對於移動平臺來講還是開銷較大,我們主要在人物選擇界面和任務簡報會話中使用景深效果來突出表現人物。

由於這些場景不需要景深的過度,我們使用一種特殊的方法來進提高移動性能。不使用depth buffer做COC混合,而是使用單獨的相機直接繪制背景圖層。在應用模糊通過後,通過將背景和前景人物組合在一起來獲得最終圖像。

為了得到更好的視覺效果,我們使用六邊形采樣模式來獲得更好的bokeh形狀。除此之外還有bokeh強度調整參數,以使其看起來更清晰,我們使用亮度值作為增量因子,2通常是一個合適的值。

性能方面為了保持性能的穩定,我們模糊背景的分辨率視模糊程度而定,更大的模糊尺寸使用更低的分辨率並且更不容易察覺,我們還使用Unity內置的曲線來描述它們之間的轉換關系。

<ignore_js_op>技術分享圖片



下圖展示了動態調整模糊大小和焦散強度的結果。

<ignore_js_op>技術分享圖片



在遊戲場景中,我們還實現了一個看起來挺酷的效果,當給最後一個敵人致命一擊的時候就會激發子彈時間,這時所有高速運動的物體都會慢下來,在下雨天我們就可以明確的看到雨滴的形狀。

為了實現這個效果,我們使用了4個代表雨滴不同速度下形態的關鍵幀,再根據時間快慢尺度對其進行垂直拉伸。 在正常的時間尺度下,雨滴看起來像一條直線,在時間變慢的時候逐漸縮短變成雨滴形狀。在這裏我們同樣使用了動畫曲線來控制拉伸,關鍵幀選擇和時間快慢的關系,調整起來非常靈活方便。

<ignore_js_op>技術分享圖片



剛才我們談到的都是一些針對移動端優化的渲染功能,下面我們來介紹一下用於動畫風格real-time CG或次世代遊戲的渲染方法。

在過去的二年中,我們陸續制作了二個短視頻,其中體現了我們的新渲染風格。(B站視頻地址:https://www.bilibili.com/video/av14260225)

<ignore_js_op>技術分享圖片



我們將它發布在了B站上,3天內獲得了B站全站月榜排行第一的位置,至今已有超過300萬的點擊量。(B站視頻地址:https://www.bilibili.com/video/av7244731)

<ignore_js_op>技術分享圖片



下面我們就來談談這些視頻中應用到的一些實時渲染CG技術。

首先我們來看看角色的渲染,我們的目標是實現完全動態的光照和陰影,所有材質都對各種光照現象做出正確的反應,包括主光源和區域環境光。這就要求我們不能使用任何在紋理上畫死的光照表現。


用於角色渲染的主要特性有:多通道Ramp的材質Shading方法,眼睛,頭發和其它各向異性材料等特殊材料的處理,以及PCSS角色軟陰影和高品質的勾線。

<ignore_js_op>技術分享圖片



首先我們來看一下多通道Ramp的Shading方法。

我們希望角色的陰影和顏色的變化可以表現出更細膩的插畫風格,所以我們使用2D ramp紋理來表示這些細微的變化,其中RGB通道分辨用於描述於不同陰影層的漫射陰影範圍。每個層都可以制定不同的顏色,這樣就能在明暗變化中做到精細的色彩變化控制。

對於卡通風格的畫面,如果上色只是純明暗變化,陰影處就會顯得比較臟,缺乏表現力,而如果提升暗處的飽和度和色相變化,整體色彩看起來就會比較鮮活。而且通過調整垂直紋理采樣坐標,我們可以實現動態的軟硬風格轉換。 從另一角度來看這種方法還間接表現了皮膚的次表面散射效果。

<ignore_js_op>技術分享圖片



下面四幅圖展示了多通道逐層上色疊加的效果。 大家可以看到通過一層層的上色疊加,皮膚層次細節會變得更加豐富。

<ignore_js_op>技術分享圖片



上下二副圖分別展示了采樣不同位置的ramp texture所對應的渲染效果,不同的ramp可以獲得各種不同的上色風格。使用hard ramp比較接近Cel-shading,soft ramp則是類似與插畫柔和的陰影層次變化。

由於我們使用了2D的ramp紋理,它們之間的變化是可以動態調整的,我們可以使用ramp mask紋理來選擇每像素的ramp軟硬以實現插畫的手繪風格。這個ramp mask紋理可以由美術直接在模型上進行繪制。我們在Unity下有一個3D paint工具,使用起來較為直觀。

<ignore_js_op>技術分享圖片



插畫風格渲染的另一個重要因素是使用紋理筆觸。我們可以使用不同的筆觸紋理圖案以獲得不同的著色風格。對於每個筆刷紋理,我們有4個通道可以存儲代表不同方向的筆刷圖案,混合使用這些筆刷可以獲得更豐富的筆刷變化。右邊的二張對比圖中,使用筆觸紋理的有著更多手繪的感覺。

<ignore_js_op>技術分享圖片



下圖顯示了應用了帶有筆觸風格的皮膚材質對不同光照角度的渲染結果。

<ignore_js_op>技術分享圖片



接下來讓我們看看如何實現高質量的邊緣光。

同樣是基於菲涅爾方法,我們有參數來控制它,比如:邊緣寬度和平滑度;除了這些全局控制參數之外,我們也使用筆刷紋理來增加一些局部變化。我們定義邊緣光既可以來自於方向光源也可以來自於環境貼圖,使用方向光我們可以按需求定義邊緣光,使用環境貼圖,我們可以根據環境光照來獲得邊緣光以顯得更真實,二者都比較有用,可以結合使用。

為避免邊邊緣光出現在不需要的區域,我們使用AO紋理和shadowmap來頻閉掉遮擋區域。我們可以看到,對比圖中左邊帶有邊緣光的形狀顯得效果更突出。

<ignore_js_op>技術分享圖片



卡通風格對於面部一般不會有太多陰影層次的變化,如果我們直接套用之前的ramp方法應用在臉部,效果就會像右側的圖看起來一樣不自然,為了改善這種情況我們使用頂點色的一個通道作為mask來控制臉部的上色層的強弱,通過壓低漫反射表現來達到想要的卡通效果。

<ignore_js_op>技術分享圖片



接下來我們來說一下高質量角色軟陰影的實現。

如果我們直接使用Unity內置的CSM陰影,在鏡頭靠近角色的時候陰影品質並不能滿足需求,所以我們就為角色單獨渲染了一張shadowmap,以確保恒定的陰影品質。為此我們還實現了基於視錐的shadowmap,根據角色的boundingbox和視錐求交集部分,以此作為渲染區域。就可以最大化陰影貼圖的使用率,

此外還使用了Variance shadow map以及PCSS來減少陰影瑕疵以及獲得自然的軟陰影效果。另外,如果要實現正確的透明材質陰影,還需要額外的通道根據材質的透明度來存儲陰影強度。我們可以從實例圖片中看到半透明的裙子可以投射出自然的陰影。

<ignore_js_op>技術分享圖片



眼睛的處理我們使用了基於物理的折射計算。普通卡通模型處理眼部的做法通常是把眼白留空,瞳孔凹陷下去,這樣在側面的時候也不會鼓出來顯得比較自然,然而如果要做眼部近距離特寫,這種做法看上去就不能令人信服。使用真實折射算法,眼球本身還是按照球面來做,然後根據視線角度算出折射系數去偏移查找貼圖對應點 。

下面對比圖顯示了有無折射的實際效果, 我們可以看到,如果沒有折射效果,眼部側面看上去較為奇怪。

<ignore_js_op>技術分享圖片



此外我們還加入了光線折射後的焦散光效果,使得眼睛的質感得到進一步增強。對於非寫實風格渲染,物理正確並不是要考慮的因素,由於卡通渲染的特殊情況,我們希望的焦散效果出現在入射光線的另一側,並且入射角度越平行看起來越明顯。

實現方法是通過入射光和眼球前向的夾角算出入射光強度,這裏我們使用inverse diffuse來模擬,再輔助fresnel公式做亮度變化,最後乘上eye caustic紋理得到最終效果。

通過下面對比圖我們可以看到如果沒有焦散效果眼睛就顯得暗淡無光缺乏質感。

<ignore_js_op>技術分享圖片



下圖展示了眼睛的折射以及頭發的各向異性高光效果。

<ignore_js_op>技術分享圖片 <ignore_js_op>技術分享圖片

賀甲大.jpg (344.27 KB, 下載次數: 0)

下載附件

2 小時前 上傳



下面為演講內容:

接下來我們就來介紹一下頭發的渲染。頭發是卡通渲染角色較為重要且獨特的部分。我們想要實現根據光源動態變化的高光和陰影漸變,並且這個實現還應具備直觀的所見即所得的色彩調節能力。

和皮膚的材質一樣,對於頭發的漫反射渲染我們同樣使用了Multi-ramp的方法,而鏡面反射高光我們則使用了二層高光做疊加,通過組合高低頻的高光成分在一起,我們可以得到滿意的結果。此外,我們還使用Glossy Map和AO紋理來進一步增強頭發的質感。

<ignore_js_op>技術分享圖片

頭發的高光渲染使用了各向異性高光,相比普通的高光使用Normal計算光照,各項異性使用Tangent作為計算基礎,因此可以使高光顯示出垂直於發絲方向的形狀。

我們在制作頭發模型的時候,如果模型拓撲較為復雜,UV展開較難做到全部垂直,我們也可以使用Flowmap來梳理高光的形狀。

<ignore_js_op>技術分享圖片

我們還使用Jittermap抖動貼圖用來增強卡通渲染頭發的質感。通過擾動切線方向來達到模擬發絲細節的高光效果。另外,通過調整Jittermap的UV scale還可以做到調整發絲的高光粗細。

<ignore_js_op>技術分享圖片

這四張圖分解展示了各個高光成分對渲染結果的影響。而右下角的則是最終的圖像。我們可以看到,結合了低頻和高頻成分的高光顯示,頭發看起來更具表現力。

<ignore_js_op>技術分享圖片

接下來讓我們看看另外一種實現Cel-shading頭發高光的實現。

我們的目標同樣是使其可以動態化,高光應根據光源和相機位置沿發絲方向移動,形狀也應該在移動中有著動態的形態變化。

Cel-shading風格的頭發高光較為獨特的形態,很難用傳統的高光計算方法來描述。同樣我們需要使用切線方向而不是法線來進行高光計算,並且需要更為特殊的方法去表現高光形狀。

<ignore_js_op>技術分享圖片

首先,我們要把每縷頭發模型在垂直方向進行UW展開,以便高光可以沿著每根發束移動。然後從將每一縷從左側向右側填充0到1,用來標識動態生成的高光形狀的起始和結束位置,我們使用幾個曲線定義的模板來描述頭發高光的基本形狀,然後使用抖動噪聲紋理來調制頭發高光的粗細變化,

材質方面有很多參數用來控制生成圖案的形狀。位置、偏移、寬度、抖動比例等,通過調整這些參數,我們可以根據需要獲得各種不同的形狀。

<ignore_js_op>技術分享圖片

我們來看另一種各向異性材質的例子:絲綢。這次我們使用了副法線方向來計算了高光反射,並使用三個高光層合成在一起獲得最終的渲染效果,我們為每一層分別設置不同的顏色,以便最終材質看起來色彩層次較為豐富。

<ignore_js_op>技術分享圖片

這裏顯示了在不同的視角下,絲綢各向異性高光的反射變化。

<ignore_js_op>技術分享圖片

我們的角色材質中還包括其它特殊的材質,例如:水晶和紗巾等半透明材質,直接使用Alpha混合不能表現出應有的質感,這就需要我們實現折射和模糊效果,這二個效果都依賴於Unity的Command buffer。

實現折射效果時,Command buffer在渲染折射前獲取已經渲染好的Backbuffer作為背景,用於折射采樣, Rgb通道設置不同折射系數,分別采樣三次來模擬色散效果。

對於模糊效果,則是用Command buffer將Backbuffer降采樣並做模糊,生成4張尺寸依次減半模糊度遞增的RenderTexture,然後根據相機距離和FOV以及材質固有的模糊參數,確定模糊程度,選擇對應的RenderTexture來完成模糊效果。

我們還對這二者的實現做了一定的優化,不對直接對Backbuffer使用全屏模糊,把物體本身作為Proxy mesh,只處理需要畫的部分。

<ignore_js_op>技術分享圖片

接下來讓我們來談談高品質勾線的方法。

對於角色和動態物體我們使用Backface勾線方法,並使用頂點色對勾線的寬度進行控制,勾線本身需要連續的頂點法線才能在銳角邊不會出現斷層,因此我們將平滑過的法線存儲在另一套頂點色裏。

此外,我們也使用頂點色來控制勾線寬度,例如:發尖處勾線會逐漸變細,我們通過在頂點顏色填充漸變為0的值以使線條寬度逐漸過渡到零。

另外,根據相機與物體之間的距離,還應有基於距離修正的勾線寬度。每種材質上也應該有對應的不同勾線顏色,所有這些功能都是高品質的勾線所必需的。

<ignore_js_op>技術分享圖片

Backface勾線方法雖然可以做到較為細致的勾線還原。但也有著自身的固有缺陷,那就是不能在非邊緣的尖銳折線處產生勾線。 而這些折線在硬表面模型上是很常見。

為了解決這個問題,我們添加一個預處理過程來提取這些邊緣,並將它們保存到額外的Mesh資源中,並使用Geometry shader繪制它們。對於這些折線我們使用了和Backface法類似的調整參數,從而使它們看起來完全相同。增加了折線的繪制之後,我們可以看到右側的圖片捕獲到了更多的勾線細節。

<ignore_js_op>技術分享圖片

勾線另一種常見方法就是在圖像空間中生成輪廓線。通過檢測場景圖像中Normal和Depth的不連續性,我們可以獲得細節較為豐富的勾線。無論場景的復雜性如何,這種方法的性能都是恒定的,我們還添加了對勾線顏色的色相、明度、飽和度的調整,使勾線更為自然。

這種方法的缺點則是較難控制勾線的寬度,如果我們想實現距離相關的線寬,我們只能在幾個像素的範圍內調整它,因此基於圖像的方法主要適用於場景輪廓渲染,對於靠近攝像頭很近的物體,我們最好使用Backface的方法。

<ignore_js_op>技術分享圖片

最後一種做法是基於筆刷的購線方法,這在離線渲染中使用的比較多,通常分為以下幾步。

  • 輪廓線提取:從Mesh上提取輪廓邊,主要分為Sharp Edge和Smooth Edge二種。
  • 連接輪廓線:根據模型的拓補關系,將相鄰的輪廓邊連接成盡可能長的輪廓線。
  • 輪廓線分段:在步驟2的基礎上,根據輪廓線上曲率和可見性的變化,將輪廓線在曲率或可見性的突變處分開。
  • 筆觸映射:將想要添加的筆觸制作成紋理,根據對應的紋理坐標映射到步驟3的輪廓線上。


這種方法可以達到更為風格化,筆觸更明顯的勾線方式,Pencil+ blender裏Freestyle render基本都是采用類似的方法,性能開銷較大,可以用於CG品質渲染,但不適合直接在遊戲中使用。

<ignore_js_op>技術分享圖片

接下來我們來看看其它特殊效果的實現,這些渲染效果在場景刻畫中同樣起到重要的作用。

<ignore_js_op>技術分享圖片

這是一段用來展示體積光的場景。我們可以看到,具有霧效的體積光配合bloom一起使用,場景表現出了較強層次和氛圍感。

<ignore_js_op>技術分享圖片

下面就來看看體積光的實現細節。

我們使用Unity內置的曲線來體積光的形狀,這在運行時也方便調整形狀,強度參數變化同樣由曲線定義。

為了進一步模擬煙霧效果,我們還使用3D noise紋理來模擬動態煙霧流動的效果。Noise煙霧本身也有一些參數可調.。例如:粒度大小、尺寸比例、噪聲強度、流動速度等。

此外,配合Cookie map還可以自定義體積光投影形狀,使用Cookie map後同時也引入了高頻的變化成分,這就需要對應增加采樣數來減少走樣,使用抖動算法可以減少采樣不足導致的走樣,我們實現了二種抖動方式:Bayer pattern和Blue noise, 通過實驗發現Blue noise配合Temporal AA可以在較低的采樣數下實現處較好的體積光效果。

<ignore_js_op>技術分享圖片

接下來我們來看一下使用Real-time GI的例子。

在這個簡單的演示場景中,我們使用Enlighten來烘焙 Real-time GI的Lightmap,然後使用動態自發光材質和體積光作為光源,我們使用AVpro插件解碼視頻文件,將其設置在自發光紋理上,並設置強度值為1以上。我們就可以獲得一個動態且明亮的面積光源,同時要記得更新GICache,以便在運行時刻可以動態更新光照環境,當與動態體積光一起使用時,整體的照明效果看起來令人印象深刻。

<ignore_js_op>技術分享圖片

對於角色上的動態AO實現,我們使用修改過的HBAO,用於指定AO區域中顏色的飽和度和色調調整,以使加入AO後的圖像顏色看起來不會變臟,通過對比圖我們可以看出,在應用了AO之後,右圖比左圖層次感更強。

<ignore_js_op>技術分享圖片

我們還重新實現了適用於卡通渲染的基於圖像的眩光效果,用於模擬鏡頭產生的鬼影和星形散射效果。這裏使用與Bloom類似的方式提取的高光區域作為輸入,然後進行多次不同方向上的卷積並應用色彩調制來獲得最終結果。

<ignore_js_op>技術分享圖片

下面我們來看幾張CG視頻中的截圖和特寫。

<ignore_js_op>技術分享圖片

這是另一組場景截圖。我們可以看到在應用了之前提到的這些渲染技術之後,整個場景可以更接近離線渲染的品質。

<ignore_js_op>技術分享圖片

下面的圖描述了上述場景中所應用到的主要渲染特性。從圖中我們可以看到這些效果包括:風格化的PBR材質、卡通風格的AO、屏幕空間勾線、屏幕空間反射以及曲面細分等。

綜合應用這些效果對於高品質的動畫風格場景渲染起著重要的作用,我們的目標是在PBR的Shading基礎上加入風格化的調整使其更具有表現力。

<ignore_js_op>技術分享圖片

場景中的大部分材質都是基於物理的渲染。我們對PBR紋理集進行了一些風格化上的適應調整,例如:對於色彩的卡通化調整,以及對於物體材質細節的強調或省略。再結合使用圖像空間的勾線來強調物體邊緣,整體場景的表現就顯得更接近動畫風格。

<ignore_js_op>技術分享圖片

下圖展示了這些材質在不同光照角度下的光影變化。

<ignore_js_op>技術分享圖片

下圖展示了光影的變化。

<ignore_js_op>技術分享圖片

除了場景渲染之外,我們再來看看其它一些動畫渲染所涉及的內容,動畫表情。

我們使用Blendshape來制作面部表情。 眼睛,嘴巴和眉毛的表情獨立為不同的部件單獨制作,然後通過我們的自定義面部表情插件,來實現表情動畫的及語音嘴型的自動映射。此外,我們還可以通過預定義不同的表情集合來在交互應用中驅動面部表情。

<ignore_js_op>技術分享圖片

在Unity中使用Humanoid作為動畫導入方式的時候,如果關節處旋轉角度較大,按照動畫品質的要求關節處的形狀就不能令人滿意。

為此我們通過在建模軟件中,建立了每關節修正的Blendshape導入到Unity當中來防止關節變形。我們使用一個自動控制腳本根據關節旋轉角度來差值混合形狀。 為了確保更好的結果,我們為每個關節分別制作了二個Blendshape,一個用於90度,另一個用於140度以補正關節變形。

另外一種方法還可以使用額外的骨骼進行關節修正。這種方法更容易制作,但是對於結構細節的表現不如使用Blendshape。

<ignore_js_op>技術分享圖片

為了可以表現更復雜的場景動態,比如流體和破碎的場景,我們可以使用Alembic格式,或者用EXR紋理作為載體從Houdini或其它DCC工具導入頂點動畫資源。Houdini對EXR紋理格式導出頂點動畫提供了很好的轉換支持,對於Real-time的應用而言,頂點動畫紋理在因為是在GPU上運行,運行效率及加載速度要快於Alembic格式。

<ignore_js_op>技術分享圖片

最後,我們來談談實時卡通渲染在今後可以繼續改進和完善的地方。

首先是實現所有類型材質完全可定制的風格化渲染,目前我們初步在人物皮膚和服裝渲染中的應用了筆刷以獲得筆觸效果。

下一步我們希望將其擴展到整個場景的渲染,比如新海誠式的場景風格,以呈現有著獨特且統一的風格化動畫風格渲染。另外一點是要進一步提高模型的渲染精度,我們希望可以實時呈現CG級的模型精度。可以嘗試使用Geometry shader或預烘培displacement map進行動態自適應的曲面細分,相比直接導入原始高模,它可以極大減少資源導入的開銷和提升運行效率。

最後是優化整套流程解決方案,使之更易於實時調整和編輯,進一步提升運行效率以適合在遊戲中使用。

<ignore_js_op>技術分享圖片

好的,以上就是我們今天有關於卡通渲染要分享的主要內容,謝謝大家!

Unite 2018 | 《崩壞3》:在Unity中實現高品質的卡通渲染