http://forum.china.unity3d.com/thread-32271-1-1.htmlhtml
咱們已經發布了Unite 2018 江毅冰的《發條樂師》、Hit-Point的《旅行青蛙》、育碧《Eagle Flight》演講分享,很多開發者在後臺留言但願小編儘快分享米哈遊技術總監賀甲《崩壞3》的案例分享,由於這場是乾貨滿滿的爆場。咱們很是感謝米哈遊以及賀甲長期以來對Unite大會的支持,因爲篇幅限制,本次演講內容將拆分紅上下二篇。算法
下面爲演講內容:
你們好,歡迎來到Unite2018參加咱們此次演講。簡單作一下自我介紹,我叫賀甲,目前在米哈遊擔任技術總監。我和個人團隊主要關注在PBR和NPR方面的實時渲染,以及用於動畫CG和遊戲的過程動畫和交互式物理的研究。目前,咱們的一部分工做是利用Unity實現高品質的卡通渲染。
此次演講的主題是《在Unity上實現高品質卡通渲染的效果》,這些方法的實現針對各個平臺的特性進行了優化,涵蓋了從移動端,到高性能PC等不一樣等級的平臺。app
咱們先來簡要介紹一下本次演講涉及到的主要方面。首先會介紹一些應用在移動端有關《崩壞3》的渲染特性。而後我會談談動畫風格CG渲染中使用的一些技術,例如:插畫風格的角色渲染、特殊材質的渲染、特效的渲染及與卡通渲染適配的後期處理等。最後一部分是關於一些雜項和對從此實現的一些展望。編輯器
首先,咱們來看看在《崩壞3》的場景中使用的一些渲染特性。
從下圖中咱們能夠看出,場景中使用了很多特效來提高表現力。例如:bloom後處理效果、動態粒子、平面反射、屏幕扭曲特效等。下面咱們將會逐一對這些效果進行解析。ide
下面展現了這些動態特效。工具
咱們來看一下如何實現高品質的反射效果。
在移動端實現高品質的反射,平面反射是一個綜合了效果和性能因素較好的辦法。一般作法是以地面爲對稱平面,將攝像機放置在對稱位置後渲染場景獲得反射結果。
爲了能表現出地面的金屬質感,首先咱們對反射結果應用六邊形採樣模糊,而後使用金屬紋理細節法線貼圖來擾動反射結果,除此以外咱們還使用了鏡面反射貼圖和菲涅爾效果來進一步加強反射質感。在一些遠離地面高度或非水平的次要反射表面上,平面反射就不在適用,爲此咱們使用環境貼圖反射做爲替代方案。
爲了儘可能減小渲染反射場景所佔用的開銷,咱們將反射分辨率限制在1/3如下,因爲反射貼圖會通過模糊處理, 即便下降了較多的分辨率也並不能明顯看出區別,而且咱們在渲染反射的過程當中還使用簡化版的材質,並忽略一些不是很重要的小物體。性能
接下來讓咱們看看另外一個效果:全屏扭曲特效的應用。
咱們在《崩壞3》的場景中較多的使用了屏幕扭曲效果,好比:刀劍的拖尾特效,時空斷裂效果,水流瀑布及其它場景效果。
在渲染扭曲效果的過程當中,咱們使用3個通道來存儲扭曲的渲染結果,2個用於存儲UV偏移,另外一個用於存儲扭曲強度Mask,扭曲強度Mask用於執行深度剪裁和基於距離的強度控制。
使用單獨的Pass渲染扭曲結果到幀緩衝紋理對於移動平臺來講開銷較大,因此咱們在最終的後處理中整合應用了扭曲效果,相比前者要快不少。 但這種方法也可能致使靠前面的物體因爲沒有分層處理而混入後面扭曲材質的問題,不過考慮到移動平臺的性能限制,相對於總體效果而言這種妥協是值得的。優化
接下來讓咱們看看bloom的實現,整個場景若是開啓HDR會使用 fp16格式的Render target,而後下采樣到原始大小的1/4大小以便以後的後處理流程使用。
首先,咱們須要指定一個亮度閾值來提取圖像中的高亮區域,實現方法也並不複雜,只需從源像素減去閾值,獲得的結構就是提取後的高亮度區域,疊加這層內容能使結果看起來更具對比而且色彩鮮豔。接下來,咱們產生4個大小依次遞半的Render target,並將其內容應用半徑逐漸增大的高斯模糊。最後咱們將這些模糊後的結果合併起來,以得到最終的bloom效果。
從下面最終的效果圖咱們能夠看到,bloom效果不只起到用來表達高亮區域的視覺效果,還對整個圖像的色彩中起着明顯的潤色做用。動畫
當完成了反射渲染,扭曲效果的及bloom 的處理後,最終就能夠將這些中間結果合成在一塊兒。咱們使用filmic tone mapping與曝光和對比度控制來將fp16 HDR的原圖像轉換爲最終的LDR幀緩衝。因爲這些合成操做都是在一個Pass中完成的,因此即便在移動設備上也能夠知足性能方面的需求。3d
下面咱們來介紹一下游戲中的天氣和雲海的實現。
咱們想要創造一個能讓玩家感覺到縱深,具備各類豐富形態以及動態光照變化的雲的渲染系統。而該系統也應該易於調整和使用,方便美術能夠創造出不一樣類型的雲層效果。這對咱們來講也是一個有趣的挑戰,接下來就讓咱們來談談這些功能。
首先讓咱們看看渲染雲所須要的資源,由於咱們想要實現能夠24小時動態變化的風格化雲的光照效果,若是直接存儲畫好的貼圖數量就會太大並且不方便調整,因此咱們使用多層着色來實現這一點。
咱們使用4個通道來表示雲的光照及陰影:基礎照明層,陰影1層,陰影2層,和邊緣光層,經過爲每一個圖層設置不一樣的顏色,咱們就能夠得到不一樣時刻的雲的色彩方案。咱們一共準備了8種形狀不一樣的雲的模板,用來構建各類不一樣的雲海景觀。
爲了構建雲海景觀,咱們使用了不少朝向屏幕發射雲朵的粒子發射器,而且使用不一樣的雲的模板以及發射模式來組合出不一樣的雲海景觀,咱們實現了各類類型的雲海以及暴風雨天氣等,這些預設都保存在天氣配置中。此外咱們還使用關鍵幀來定義天空背景和雲彩的顏色。隨着時間的流逝,雲的色彩就根據關鍵幀來變化。
在性能方面主要的開銷是Overdraw問題,若是咱們按照固定控制的Pattern來發射雲雖然能夠以最小的Overdraw來得到較好的雲海密度,但可能會看起來較爲重複,加入產生位置的隨機因素能夠解決這個問題,但要想得到看起來不那麼稀疏的雲海效果就須要相比固定Pattern更多的粒子數量,咱們對於粒子發射配置都有細緻的參數能夠調整,以便在兩者之間能夠找到較好的權衡點。
這是一個24小時晝夜變化的雲海景觀。
這是另外一種雲海景觀的晝夜變化。
這是暴風雲閃電的場景。
如今讓咱們來看看遊戲場景中使用的天氣系統。
咱們主要經過全局霧效,Skybox顏色和方向光的設置來改變場景的天氣和氛圍。對於霧效一樣有許多參數能夠調整。咱們給霧效基於深度劃分爲遠近距離二個區間,遠近區間均可以設置不一樣的顏色和強度值來創造各類各樣的氣氛。Skybox也能夠控制天空顏色漸變,雲的受光及陰影顏色等。綜合上述調整選項,咱們就能夠建立 晴天,雨天和大霧,多雲和夜間等天氣。
另外人物的光照也會受環境的影響,主要的光照顏色由方向光決定,局部區的陰影的變化,好比:角色走進陰影區域,由一些從關卡編輯器中手工放置的Lighting volume定義。
讓咱們再來看看遊戲中使用景深的狀況。
移動遊戲中使用景深通常並不常見,由於常見的景深實現對於移動平臺來說仍是開銷較大,咱們主要在人物選擇界面和任務簡報會話中使用景深效果來突出表現人物。
因爲這些場景不須要景深的過分,咱們使用一種特殊的方法來進提升移動性能。不使用depth buffer作COC混合,而是使用單獨的相機直接繪製背景圖層。在應用模糊經過後,經過將背景和前景人物組合在一塊兒來得到最終圖像。
爲了獲得更好的視覺效果,咱們使用六邊形採樣模式來得到更好的bokeh形狀。除此以外還有bokeh強度調整參數,以使其看起來更清晰,咱們使用亮度值做爲增量因子,2一般是一個合適的值。
性能方面爲了保持性能的穩定,咱們模糊背景的分辨率視模糊程度而定,更大的模糊尺寸使用更低的分辨率而且更不容易察覺,咱們還使用Unity內置的曲線來描述它們之間的轉換關係。
下圖展現了動態調整模糊大小和焦散強度的結果。
在遊戲場景中,咱們還實現了一個看起來挺酷的效果,當給最後一個敵人致命一擊的時候就會激發子彈時間,這時全部高速運動的物體都會慢下來,在下雨天咱們就能夠明確的看到雨滴的形狀。
爲了實現這個效果,咱們使用了4個表明雨滴不一樣速度下形態的關鍵幀,再根據時間快慢尺度對其進行垂直拉伸。 在正常的時間尺度下,雨滴看起來像一條直線,在時間變慢的時候逐漸縮短變成雨滴形狀。在這裏咱們一樣使用了動畫曲線來控制拉伸,關鍵幀選擇和時間快慢的關係,調整起來很是靈活方便。
剛纔咱們談到的都是一些針對移動端優化的渲染功能,下面咱們來介紹一下用於動畫風格real-time CG或次世代遊戲的渲染方法。
在過去的二年中,咱們陸續製做了二個短視頻,其中體現了咱們的新渲染風格。(B站視頻地址:https://www.bilibili.com/video/av14260225)
咱們將它發佈在了B站上,3天內得到了B站全站月榜排行第一的位置,至今已有超過300萬的點擊量。(B站視頻地址:https://www.bilibili.com/video/av7244731)
下面咱們就來談談這些視頻中應用到的一些實時渲染CG技術。
首先咱們來看看角色的渲染,咱們的目標是實現徹底動態的光照和陰影,全部材質都對各類光照現象作出正確的反應,包括主光源和區域環境光。這就要求咱們不能使用任何在紋理上畫死的光照表現。
用於角色渲染的主要特性有:多通道Ramp的材質Shading方法,眼睛,頭髮和其它各向異性材料等特殊材料的處理,以及PCSS角色軟陰影和高品質的勾線。
首先咱們來看一下多通道Ramp的Shading方法。
咱們但願角色的陰影和顏色的變化能夠表現出更細膩的插畫風格,因此咱們使用2D ramp紋理來表示這些細微的變化,其中RGB通道分辨用於描述於不一樣陰影層的漫射陰影範圍。每一個層均可以制定不一樣的顏色,這樣就能在明暗變化中作到精細的色彩變化控制。
對於卡通風格的畫面,若是上色只是純明暗變化,陰影處就會顯得比較髒,缺少表現力,而若是提高暗處的飽和度和色相變化,總體色彩看起來就會比較鮮活。並且經過調整垂直紋理採樣座標,咱們能夠實現動態的軟硬風格轉換。 從另外一角度來看這種方法還間接表現了皮膚的次表面散射效果。
下面四幅圖展現了多通道逐層上色疊加的效果。 你們能夠看到經過一層層的上色疊加,皮膚層次細節會變得更加豐富。
上下二副圖分別展現了採樣不一樣位置的ramp texture所對應的渲染效果,不一樣的ramp能夠得到各類不一樣的上色風格。使用hard ramp比較接近Cel-shading,soft ramp則是相似與插畫柔和的陰影層次變化。
因爲咱們使用了2D的ramp紋理,它們之間的變化是能夠動態調整的,咱們可使用ramp mask紋理來選擇每像素的ramp軟硬以實現插畫的手繪風格。這個ramp mask紋理能夠由美術直接在模型上進行繪製。咱們在Unity下有一個3D paint工具,使用起來較爲直觀。
插畫風格渲染的另外一個重要因素是使用紋理筆觸。咱們可使用不一樣的筆觸紋理圖案以得到不一樣的着色風格。對於每一個筆刷紋理,咱們有4個通道能夠存儲表明不一樣方向的筆刷圖案,混合使用這些筆刷能夠得到更豐富的筆刷變化。右邊的二張對比圖中,使用筆觸紋理的有着更多手繪的感受。
下圖顯示了應用了帶有筆觸風格的皮膚材質對不一樣光照角度的渲染結果。
接下來讓咱們看看如何實現高質量的邊緣光。
一樣是基於菲涅爾方法,咱們有參數來控制它,好比:邊緣寬度和平滑度;除了這些全局控制參數以外,咱們也使用筆刷紋理來增長一些局部變化。咱們定義邊緣光既能夠來自於方向光源也能夠來自於環境貼圖,使用方向光咱們能夠按需求定義邊緣光,使用環境貼圖,咱們能夠根據環境光照來得到邊緣光以顯得更真實,兩者都比較有用,能夠結合使用。
爲避免邊邊緣光出如今不須要的區域,咱們使用AO紋理和shadowmap來頻閉掉遮擋區域。咱們能夠看到,對比圖中左邊帶有邊緣光的形狀顯得效果更突出。
卡通風格對於面部通常不會有太多陰影層次的變化,若是咱們直接套用以前的ramp方法應用在臉部,效果就會像右側的圖看起來同樣不天然,爲了改善這種狀況咱們使用頂點色的一個通道做爲mask來控制臉部的上色層的強弱,經過壓低漫反射表現來達到想要的卡通效果。
接下來咱們來講一下高質量角色軟陰影的實現。
若是咱們直接使用Unity內置的CSM陰影,在鏡頭靠近角色的時候陰影品質並不能知足需求,因此咱們就爲角色單獨渲染了一張shadowmap,以確保恆定的陰影品質。爲此咱們還實現了基於視錐的shadowmap,根據角色的boundingbox和視錐求交集部分,以此做爲渲染區域。就能夠最大化陰影貼圖的使用率,
此外還使用了Variance shadow map以及PCSS來減小陰影瑕疵以及得到天然的軟陰影效果。另外,若是要實現正確的透明材質陰影,還須要額外的通道根據材質的透明度來存儲陰影強度。咱們能夠從實例圖片中看到半透明的裙子能夠投射出天然的陰影。
眼睛的處理咱們使用了基於物理的折射計算。普通卡通模型處理眼部的作法一般是把眼白留空,瞳孔凹陷下去,這樣在側面的時候也不會鼓出來顯得比較天然,然而若是要作眼部近距離特寫,這種作法看上去就不能使人信服。使用真實折射算法,眼球自己仍是按照球面來作,而後根據視線角度算出折射係數去偏移查找貼圖對應點 。
下面對比圖顯示了有無折射的實際效果, 咱們能夠看到,若是沒有折射效果,眼部側面看上去較爲奇怪。
此外咱們還加入了光線折射後的焦散光效果,使得眼睛的質感獲得進一步加強。對於非寫實風格渲染,物理正確並非要考慮的因素,因爲卡通渲染的特殊狀況,咱們但願的焦散效果出如今入射光線的另外一側,而且入射角度越平行看起來越明顯。
實現方法是經過入射光和眼球前向的夾角算出入射光強度,這裏咱們使用inverse diffuse來模擬,再輔助fresnel公式作亮度變化,最後乘上eye caustic紋理獲得最終效果。
經過下面對比圖咱們能夠看到若是沒有焦散效果眼睛就顯得暗淡無光缺少質感。
下圖展現了眼睛的折射以及頭髮的各向異性高光效果。
因爲篇幅限制,上篇的內容就先分享到這裏,明天咱們將繼續本次演講內容,分享髮色渲染、光照、後期特效處理等一系列內容。