一種強調動態感的殘影特效製作方法
先放一張效果。嗯,實驗性質,感覺還不錯。
很多Unity項目里角色殘影的做法都是用SkinnedMeshRenderer.BakeMesh生成角色在特定幾幀的靜態模型,再附加一個半透明的材質。雖然說確實也是生成了殘影,但是動態感並不強。優點是做起來簡單,對系統資源的消耗較低。好,轉回正題。現在說說我做這個效果的思路,鑒於眾所周知的原因,本章之中不附帶任何源碼。
分析問題的原則就是把複雜的問題分為幾個簡單的問題。我們從後往前推,這個效果最終需要的是一個半透的片兒,效果大致如下:那麼剩下的問題是:第一,如何獲得這張帶有動態線效果的貼圖。第二,如何動態生成一個mesh匹配這個角色。第一個問題是比較棘手的,和shader有關。第二個相對簡單,無非就是對一個簡單多邊形頂點的控制。
我們把複雜苛刻的條件簡化一下,假設現在你已經有了一張角色的截圖,那麼怎麼通過這張圖畫出動態線出來。由上圖轉換為下圖。雖然看起來很神奇,其實原理很簡單。就是在tex2D(_Texture , o.uv)的時候,UV的x值統統設為0.5。代碼片段如下:
fixed2 newUV = o.uv;newUV.x = 0.5;fixed4 c = tex2D(_BlurCaptureTexture , newUV);return c;
我已經想不到能比這段fragment更簡單的代碼了。所有像素都取水平方向最中間那個點的顏色。
之後再疊上一層半透明的mask,就能得到我們想要的效果。是不是覺得很簡單。當然,複雜問題簡單化以後每一個問題都不難。但是麻煩的是你要動腦子解決一堆問題。比如下面一個:我如何能獲得這個角色在這一幀的截圖?
這個就比較麻煩了。首先第一個想到的是RenderToTexture。然而全屏截一張圖並沒有什麼意義,畢竟角色占整個屏幕的範圍很小,截這麼大一張圖除了徒勞地增加一大堆drawcall對你的幫助不大。關於這個問題我想了好幾個方法,但是都不太理想。最後的解決方案是:假設這個項目攝像機是跟隨角色運動的,假設角色基本上就處在屏幕水平位置的正中間。那麼問題就變得好辦了。
如圖所示,建立一個新的攝像機,所有的屬性和原來的攝像機完全相同。但是只渲染主角所在的層。然後從用原攝像機的位置和物體的位置算出一條法線,讓新攝像機沿著法線向前移動一定的距離,就可以在保證原攝像機角度不變的前提下獲得一個角色大小適中的截圖。原攝像機視角下渲染的圖
在開始出現虛影的那一幀調整好新攝像機的位置
新攝像機下渲染出來的圖
當然,我承認這個方法並不完美。首先並不是所有項目都能保證鏡頭一直跟著角色走(比如《戰神》)。又或者並不能保證這個效果只能使用在主角上,這也就意味著角色在鏡頭裡的水平位置並不一定在正中間。不能滿足以上兩個條件的時候這種處理新鏡頭的方式就會失靈。變通的做法是在每個角色身上事先掛好一個攝像機來替代自動調整位置的攝像機,這樣可以自己控制攝像機的位置。但是也會產生別的問題,比如截圖時攝像機的旋轉方向和原攝像機不同。在這個基礎上你還可以寫腳本強行去旋轉新攝像機。這只是我的設想,並沒有實踐。我很懷疑這麼做可能又會引起其他的問題。總之我沒有想到什麼特別完美的解決方案。在特定條件之下妥協的方案是不完美的,但是確實能解決問題。我並不是一個程序員,也從來不追求所謂的「完美」。作為一個TA我只關心我的工作是不是能解決問題。我覺得這是TA和程序最大的區別。如果項目確實有更高更精準的需求,我會再去想想怎麼解決。就目前來看這個做法已經能滿足美術對特效的需求了。需要說明的是,我是很反對在移動設備上做RT的。但是這個效果對性能的負擔還在能接受的範圍之內。新鏡頭一直處在關閉的狀態,只有在需要的那一幀渲染一下,然後立刻關掉。而且渲染的圖像素非常低(高了反而沒有那種模糊的效果)。無論是對內存還是對GPU來說,只要是近一兩年的主流機型都能應付得來。既然圖的問題都解決了,那麼剩下就是那個mesh的問題。其實這個問題比上面簡單得多。無非是根據主角移動的方向和速度,將四個點的其中兩個點每一幀都往「後」移動,產生被拉長的效果。當然你可以寫腳本每一幀更新新mesh的頂點位置,而我用了個更簡單的方法。我在max里做了一個帶蒙皮的mesh。把虛擬體綁定在蒙皮里。這樣在Unity里我只要控制虛擬體的位移就可以輕鬆達到效果。在max里做好模型和蒙皮,後面的處理就會很簡單。
最後的最後就是把這些過程按部就班地寫成C#腳本,掛在物體上。這個過程並不難,只是很繁瑣,很容易出bug。需要花點時間和耐心。在之後可以去打磨一些細節,比如淡入淡出的效果,比如對殘影的顏色進行調節(比如我這個列子最後增強了殘影的對比度)。推薦閱讀:
※遊戲中角色/武器的一款皮膚是如何被設計出來的?過程有哪些節點?
※暗黑 2 的遊戲畫面、圖標與 UI 放到今天能算什麼水平?
※有什麼美術基礎的書推薦?
※曼奇立德的原畫水平在國內行業中是怎樣的水準?