1. 程式人生 > 其它 >屏幕後處理效果系列之常見後處理效果篇

屏幕後處理效果系列之常見後處理效果篇

1.1 前言

在系列第一篇中,我們學習了用於影象模糊的相關演算法,在探究這些演算法效率高低的同時,深入理解了這些演算法的核心思想,這些思想將會被應用於許多後處理效果中。接下來,我們將學習一些常見的屏幕後處理效果的實現方式。


1.2 基礎知識

Bloom(Glow)特效是遊戲中應用最普遍的一種屏幕後處理特效。表現為高光物體帶有泛光效果,使畫面的光影表現更加優秀。Bloom通常會搭配HDR和ToneMapping來得到更好的效果。

首先我們需要簡單瞭解一下什麼是HDR和ToneMapping。電子裝置可以顯示的亮度範圍有限,對於RGB三個通道,每個通道8bit,由此以來可以顯示(2^8)^3=16777216種顏色,這個範圍被稱為低動態範圍(Low-Dynamic Range)。這個範圍是一個經驗亮度範圍,在這個範圍內不會對人眼產生傷害,而超出這個範圍的顏色空間被稱為高動態範圍(High-Dynamic Range)。現實生活中的亮度是沒有範圍限制的,想要表達更多的亮度,RGB每個通道需要擴充到12位乃至更多。運算完成後,在進行輸出時需要通過ToneMapping將HDR空間中的顏色對映到LDR空間中,再在顯示器上進行顯示。

現實生活中,Bloom產生的原因是人眼晶狀體的散射,例如在強光照射的時候,會有看不清的情況發生。於是使用Bloom來表現高光溢位的效果從而模擬這種現象。

關於HDR 、 LDR、ToneMapping的更多知識點可以學習《漫談HDR和色彩管理》

通用的Bloom特效的製作方式是將影象高亮的部分通過卷積進行模糊之後再疊加到原影象上。在《屏幕後處理效果系列之影象模糊演算法篇》課程中,我們介紹了各種影象模糊的演算法,選擇使用效率最高的Dual Blur的方式進行模糊處理。


1.3 Unity實現

首先設定閾值,取樣圖片,對於圖片中超過閾值的畫素被判定為高亮部分。高亮部分,保留顏色,其餘部分歸0,儲存在一張RT中。

BloomMaterial.SetFloat("_Threhold", threshold);
BloomMaterial.SetFloat("_Intensity", intensity);
RenderTexture HighLighrRT=RenderTexture.GetTemporary(src.descriptor);
Graphics.Blit(src, HighLighrRT, BloomMaterial, 0);
 

Boom.shader:
Pass
{
    CGPROGRAM

    #pragma vertex vert_img
    #pragma fragment frag

    fixed4 frag(v2f_img input) : SV_Target
    {
        float4 color = tex2D(_MainTex, input.uv);
        return max(color - _Threhold, 0) * _Intensity;
    }

    ENDCG
}

  

接著,將得到的高亮部分進行模糊處理後疊加在原圖上:

Pass
{
    CGPROGRAM

    #pragma vertex vert_img
    #pragma fragment frag
    sampler2D _CompositeTex;
    float4    _CompositeColor;
    fixed4 frag(v2f_img input) : SV_Target
{
    float4 mainColor = tex2D(_MainTex,input.uv);
    float4 compositeColor = tex2D(_CompositeTex, input.uv);
    return saturate(mainColor + compositeColor);
}
    ENDCG
}

  

得到效果如圖:

原圖如下:

類似地,模仿實現“光劍”效果:


1.4 小結

Bloom效果可以說是遊戲中使用最為普遍的屏幕後處理特效了,實現也較為簡單。從此我們可以學習到通過模糊處理產生可以使顏色自然平滑地暈開,通過顏色疊加可以使亮度提升。

影響Bloom效果效能最大的因素是進行模糊處理的開銷。參考《屏幕後處理效果系列之影象模糊演算法篇》的內容,建議選擇Dual Blur演算法進行處理。

大家可以按照這個公式再對比一下前面函式DirectBRDFSpecular計算的是否正確。

完整課程可戳此檢視《屏幕後處理效果系列之常見後處理效果篇》。