Unity鏡頭光暈模擬開源庫

【博物納新】是UWA旨在爲開發者推薦新穎、易用、有趣的開源項目,幫助你們在項目研發之餘發現世界上的熱門項目、前沿技術或者使人驚歎的視覺效果,並探索將其應用到本身項目的可行性。不少時候,咱們並不知道本身想要什麼,直到某一天咱們遇到了它。html

更多精彩內容請關注:lab.uwa4d.com性能


此開源庫的鏡頭光暈效果是由Pseudo Lens Flare簡化修改的Unity版本。本文主要分析了Lens Flare開源庫的大體實現過程及部分代碼解讀。spa

效果展現

開源庫連接:https://lab.uwa4d.com/lab/5b564072d7f10a201fd8d451code


效果實現

以示例項目爲例,下圖展現了光暈效果的主要產生過程,通過了下采樣、Ghost、半徑扭曲、散射重影和兩次虛化效果,最後疊加原始圖像獲得最終效果。
orm

一、Downsampling/Thresholdhtm

第一步,將原始圖像作一次下采樣,同時經過參數_Sub控制只保留畫面中亮的部分,經過參數_Mul調節保留亮度(默認參數_Mul=0.5)。blog

fixed4 frag (v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    col = max(col-_Sub, 0);
    col *= _Mul;
    return col;
}

相似於原Blog中的第一步效果:
圖片

二、Ghosts開發

這一步模擬光暈效果中的斑點,經過三個參數能夠控制斑點的個數、擴散和衰減。如下爲參數調節的效果圖及Shader部分代碼。
rem

fixed4 frag(v2f i) : SV_Target
{
    fixed4 col = tex2D(_MainTex, i.uv);
    float2 uv = i.uv - float2(0.5, 0.5);
    for (int k = 3; k < _NumGhost + 3; k++) {
        if (k & 1) {
            col += tex2D(_MainTex, _Displace * -uv / (k >> 1) + float2(0.5, 0.5));
        }
        else {
            col += tex2D(_MainTex, uv / (k >> 1) + float2(0.5, 0.5));
            }
    }
    col *= pow(1 - length(uv) / .707, _Falloff);
    return col;
}

三、RadialWarp

這一步是用於模擬一個外部的光環,首先根據須要的光環半徑HaloWidth計算獲得一個半徑扭曲的圖像,再添加光環的衰減效果。便可獲得一個根據原圖像移動的光環效果。

fixed4 frag(v2f i) : SV_Target
{
    fixed4 col = fixed4(0,0,0,0);
    
    float2 ghostVec = i.uv - .5;
    //歸一化後減光環半徑獲得光環頂點位置
    float2 haloVec = normalize(ghostVec)*-_HaloWidth;
    //根據光環位置獲得每一個像素的權重,爲一個白色的圓環
    float weight = length(float2(0.5, 0.5) - (i.uv + haloVec)) / .707;
    //添加衰減效果
    weight = pow(1.0 - weight, _HaloFalloff);
    col += tex2D(_MainTex, i.uv + haloVec) * weight;
    col = max(0, col - _HaloSub);
    return col;
}

四、Aberration

將第2步和第3步的圖像疊加,便可獲得一個初步成型的光暈效果圖(下圖左)。這一步要模擬出光線的失真效果(下圖右)。

以下,爲計算色彩失真的Shader核心計算代碼,其中_ChromaticAberration_Spectrum是一個1x3的三像素RGB圖像。

fixed4 frag (v2f i) : SV_Target
{
    //計算失真位置
    float2 coords = 2.0 * i.uv - 1.0;
    float2 end = i.uv - coords * _ChromaticAberration_Amount;
    
    //uv差值
    float2 diff = end - i.uv;
    //失真採樣像素數
    int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, 16);
    //每一個像素的uv差
    float2 delta = diff / samples;
    float2 pos = i.uv;
    half3 sum = (0.0).xxx, filterSum = (0.0).xxx;


    //循環採樣計算失真像素點的uv和色值
    for (int i = 0; i < samples; i++)
    {
        half t = (i + 0.5) / samples;
        half3 s = tex2Dlod(_MainTex, float4(pos, 0, 0)).rgb;
        half3 filter = tex2Dlod(_ChromaticAberration_Spectrum, float4(t, 0, 0, 0)).rgb;


        sum += s * filter;
        filterSum += filter;
        pos += delta;
    }


    return float4(sum / filterSum, 1);
}

最後將獲得的圖像作兩次Blur效果,再與原圖像混合後便可獲得鏡頭光暈的模擬效果。


小結

本文主要分析了Lens Flare開源庫的大體實現過程及部分代碼解讀。因爲目前的版本效果運用了大量的後處理,渲染開銷較高,在移動端性能較差,並不建議直接在移動端使用。但其模擬的鏡頭光暈效果逼真,建議有須要的朋友能夠一試。


快用UWA Lab合輯Mark好項目!

請輸入圖片描述

今天的推薦就到這兒啦,或者它可直接使用,或者它須要您的潤色,或者它啓發了您的思路......

請不要吝嗇您的點贊和轉發,讓咱們知道咱們在作對的事。固然若是您能夠留言給出寶貴的意見,咱們會越作越好。

相關文章
相關標籤/搜索