1. 程式人生 > >我發現了Unity3D的2D Light Renderer, 隨後就把它抄了過來

我發現了Unity3D的2D Light Renderer, 隨後就把它抄了過來

.  前幾個月,偶然在群裡看到有人討論Unity3D光照,於是我又萌生了一個新的目標————把它抄過來!

.  眾所周知,3D渲染的整個流水線都跟光照密不可分,相關的技術更是數不甚數,而2D遊戲的光照通常被人忽略,因為2D遊戲大多數都是貼圖疊加,要什麼效果,美術直接畫出來就完事了,所以大多數2D遊戲引擎就不過是個貼圖引擎,幹著渲染的工作卻沒有一點渲染的技術含量。

.  即使是2D遊戲,運用好光源也可以把品質提升一個檔次,但就如前面所說,做2D引擎的不提供這個功能,用2D引擎的不知道這個技術,以至於大部分有動態光效的2D遊戲都是外國貨。


.  進入正題,記錄一下我花了2個週末實現的2D光源編輯。

效果圖

大體思路

先生成光照面積,在後期階段通過面積全屏取樣輸出即可,其難點就在於生成光照面積。

光照面積又分內面積和外面積,內面積就是發光的部分,光線不會衰減,外面積則是輻射範圍,光線會逐漸衰減,在這個前提下,光照面積還分圓形面積和多邊形面積。

圓形面積生成:

通過圓形和半徑生成內面積,再通過給定的輻射度生成外面積,這個形狀看起來像是一個環,之後再用三角形填充內面積以及環,最終生成的樣子是這樣的。

多邊形面積生成:

通過給定的頂點生成內面積,再通過給定的輻射度生成外面積,思路跟圓形是一樣的,但多邊形有兩個略為棘手的問題。其一是多邊形的形狀是不可控的,如果是凹多邊形,則光照面積會疊加,這會導致疊加的部分被多次光照。其二是多邊形並非像圓形一樣均勻的形狀,想象一下,同一個光源散發出來的光在相同距離的情況下衰減程度應該是一樣的,拿圓形光源來說,光從內面積邊緣發出,最終抵達外面積邊緣,當光線剛發出時(在內面積邊緣時)其衰減值為1(最大值),當光線抵達終點後(在外面積邊緣時)其衰減值為0(最小值),而圓形是一個均勻的形狀,因此它任何角度都滿足這一條件,而多邊形則需要通過一點點的計算代價來做到這一點。

解決第一點:求得最大凸包即可。

解決第二點,計算外面積的時候,用圓角來代替多邊形的銳角。

最終生成的樣子是這樣的。


最終效果

有線段繪製

無線段繪製

Github傳送