2015年9月28日 星期一

Blacksmith中的皺紋貼圖處理


作者:TORBJORN LAEDRE
原文:http://blogs.unity3d.com/2015/05/28/wrinkle-maps-in-the-blacksmith/


在我們籌備The Blacksmith短片專案的時候,我們從未真的考慮過將自訂皮膚著色器提升到成為一個專門的工作。 不過,我們還是想看看能否用一些我們能做的簡單方式,讓角色的表情更生動。

在一陣腦力激盪之後,我們決定為專案增加一個執行皺紋貼圖的形狀融合(blendshape) ,為了讓表情加上深度和細節,我們確信如果能讓皺紋同時作用法線和遮擋, 採用標準著色器(Standard shader)將會給出最棒的效果 ,同時,我們也希望能通過某種方法,來對特定的臉部表情表達加以限制。

皺紋貼圖驅動設計(Enter Wrinkle Maps Driver )


我們做了一個組件讓動畫器(Animator)能夠定義皺紋層,網格的每個形狀融合都各自對應一層。 皺紋層的定義包含了紋理貼圖、強度指示器以及一組匹配於人臉各部分的遮蔽權值。 因為使用了遮蔽權值,每一個具體的皺紋層都可能作用於1~4個面部區域,並對每個區域造成不同程度的影響。



因為我們希望能夠在任何情況下混合多達四個不同的表情,單單混合就需要用到11個紋理採樣(兩個基礎紋理,八個細節紋理和一個遮罩紋理)。 對此,唯一實際作法,就是將皺紋貼圖在一個螢幕外的預渲染通道中組合起來。

我們發現ARGB2101010渲染材質格式在此非常切合我們的需求,因為它允許我們僅用10bit通道中的兩個來處理法線,而剩下的一個用於存放遮蔽信息。 在每一幀,皺紋貼圖組件都會尋找出四個最具影響的形狀融合,然後更具權值分層渲染。



一旦我們在螢幕空間內完成所有的皺紋數據合成,剩下的唯一要做的事情就是:重定向我們用於繪制人臉的標準著色器的法線和遮蔽數據的輸入。

在實際操作中,這僅需在表面著色器(surface shader)的主函數中添加很少幾行代碼。 


//皺紋貼圖被啓用時,於屏幕空間緩衝中對法線和遮蔽信息進行採樣
#ifdef WRINKLE_MAPS
float3 normalOcclusion =
tex2D(_NormalAndOcclusion, IN.screenPos.xy / IN.screenPos.w).rgb;
o.Occlusion = normalOcclusion.r;
#ifdef _NORMALMAP
o.Normal.xy = normalOcclusion.gb * 2.f - 1.f;
o.Normal.z = sqrt(saturate(1.f - dot(o.Normal.xy, o.Normal.xy)));
#endif
#endif

最終結果(Final Results) 


極度憤怒表情下,對比皺紋貼圖處理所帶來的額外細節。



我們還額外編寫了多種除錯輸出模式,使我們能夠輕鬆查看完全融合的遮蔽和法線貼圖。有助於定位各個組件在最終結果中究竟起何作用。



我們已經把這一功能單獨抽離成為一個展示專案,你可以從Asset Store下載。

專案只有角色的頭部以及兩個我們在Blacksmith短片中用到的表情,不過對於啓發你在自己的遊戲中應用皺紋貼圖而言,這應當是一個相當不錯的開頭。

沒有留言:

張貼留言

著作人