Shaderlab Notizen 8 屏幕水幕特效

一、Shader實(shí)現(xiàn)部分

//-----------------------------------------------【Shader腳本說(shuō)明】---------------------
//       屏幕水幕特效的實(shí)現(xiàn)代碼-Shader腳本部分  
//--------------------------------------------------------------------------------------------

Shader "Shader/ScreenWaterDropEffect"  
{  
    //------------------------------------【屬性值】------------------------------------  
    Properties  
    {  
        //主紋理  
        _MainTex ("Base (RGB)", 2D) = "white" {}  
        //屏幕水滴的素材圖  
        _ScreenWaterDropTex ("Base (RGB)", 2D) = "white" {}  
        //當(dāng)前時(shí)間  
        _CurTime ("Time", Range(0.0, 1.0)) = 1.0  
        //X坐標(biāo)上的水滴尺寸  
        _SizeX ("SizeX", Range(0.0, 1.0)) = 1.0  
        //Y坐標(biāo)上的水滴尺寸  
        _SizeY ("SizeY", Range(0.0, 1.0)) = 1.0  
        //水滴的流動(dòng)速度  
        _DropSpeed ("Speed", Range(0.0, 10.0)) = 1.0  
        //溶解度  
        _Distortion ("_Distortion", Range(0.0, 1.0)) = 0.87  
    }  

    //------------------------------------【唯一的子著色器】------------------------------
    SubShader  
    {  
        Pass  
        {  
            //設(shè)置深度測(cè)試模式:渲染所有像素.等同于關(guān)閉透明度測(cè)試(AlphaTest Off)  
            ZTest Always  

            //===========開(kāi)啟CG著色器語(yǔ)言編寫(xiě)模塊===========  
            CGPROGRAM  

            //編譯指令:告知編譯器頂點(diǎn)和片段著色函數(shù)的名稱  
            #pragma vertex vert  
            #pragma fragment frag  
            #pragma fragmentoption ARB_precision_hint_fastest  
            //編譯指令: 指定著色器編譯目標(biāo)為Shader Model 3.0  
            #pragma target 3.0  

            //包含輔助CG頭文件  
            #include "UnityCG.cginc"  

            //外部變量的聲明  
            uniform sampler2D _MainTex;  
            uniform sampler2D _ScreenWaterDropTex;  
            uniform float _CurTime;  
            uniform float _DropSpeed;  
            uniform float _SizeX;  
            uniform float _SizeY;  
            uniform float _Distortion;  
            uniform float2 _MainTex_TexelSize;  

            //頂點(diǎn)輸入結(jié)構(gòu)  
            struct vertexInput  
            {  
                float4 vertex : POSITION;//頂點(diǎn)位置  
                float4 color : COLOR;//顏色值  
                float2 texcoord : TEXCOORD0;//一級(jí)紋理坐標(biāo)  
            };  

            //頂點(diǎn)輸出結(jié)構(gòu)  
            struct vertexOutput  
            {  
                half2 texcoord : TEXCOORD0;//一級(jí)紋理坐標(biāo)  
                float4 vertex : SV_POSITION;//像素位置  
                fixed4 color : COLOR;//顏色值  
            };  

            //--------------------------------【頂點(diǎn)著色函數(shù)】-----------------------------  
            // 輸入:頂點(diǎn)輸入結(jié)構(gòu)體  
            // 輸出:頂點(diǎn)輸出結(jié)構(gòu)體  
            //---------------------------------------------------------------------------------  
            vertexOutput vert(vertexInput Input)  
            {  
                //【1】聲明一個(gè)輸出結(jié)構(gòu)對(duì)象  
                vertexOutput Output;  

                //【2】填充此輸出結(jié)構(gòu)  
                //輸出的頂點(diǎn)位置為模型視圖投影矩陣乘以頂點(diǎn)位置撮珠,也就是將三維空間中的坐標(biāo)投影到了二維窗口  
                Output.vertex = mul(UNITY_MATRIX_MVP, Input.vertex);  
                //輸出的紋理坐標(biāo)也就是輸入的紋理坐標(biāo)  
                Output.texcoord = Input.texcoord;  
                //輸出的顏色值也就是輸入的顏色值  
                Output.color = Input.color;  

                //【3】返回此輸出結(jié)構(gòu)對(duì)象  
                return Output;  
            }  

            //--------------------------------【片段著色函數(shù)】-----------------------------  
            // 輸入:頂點(diǎn)輸出結(jié)構(gòu)體  
            // 輸出:float4型的顏色值  
            //---------------------------------------------------------------------------------  
            fixed4 frag(vertexOutput Input) : COLOR  
            {  
                //【1】獲取頂點(diǎn)的坐標(biāo)值  
                float2 uv = Input.texcoord.xy;  

                //【2】解決平臺(tái)差異的問(wèn)題伴逸。校正方向,若和規(guī)定方向相反狡耻,則將速度反向并加1  
                #if UNITY_UV_STARTS_AT_TOP  
                if (_MainTex_TexelSize.y < 0)  
                    _DropSpeed = 1 - _DropSpeed;  
                #endif  

                //【3】設(shè)置三層水流效果陪踩,按照一定的規(guī)律在水滴紋理上分別進(jìn)行取樣  
                float3 rainTex1 = tex2D(_ScreenWaterDropTex, float2(uv.x * 1.15* _SizeX, (uv.y* _SizeY *1.1) + _CurTime* _DropSpeed *0.15)).rgb / _Distortion;  
                float3 rainTex2 = tex2D(_ScreenWaterDropTex, float2(uv.x * 1.25* _SizeX - 0.1, (uv.y *_SizeY * 1.2) + _CurTime *_DropSpeed * 0.2)).rgb / _Distortion;  
                float3 rainTex3 = tex2D(_ScreenWaterDropTex, float2(uv.x* _SizeX *0.9, (uv.y *_SizeY * 1.25) + _CurTime * _DropSpeed* 0.032)).rgb / _Distortion;  

                //【4】整合三層水流效果的顏色信息,存于finalRainTex中  
                float2 finalRainTex = uv.xy - (rainTex1.xy - rainTex2.xy - rainTex3.xy) / 3;  

                //【5】按照f(shuō)inalRainTex的坐標(biāo)信息荒吏,在主紋理上進(jìn)行采樣  
                float3 finalColor = tex2D(_MainTex, float2(finalRainTex.x, finalRainTex.y)).rgb;  

                //【6】返回加上alpha分量的最終顏色值  
                return fixed4(finalColor, 1.0);  

            }  

            //===========結(jié)束CG著色器語(yǔ)言編寫(xiě)模塊===========  
            ENDCG  
        }  
    }  
}

二敛惊、腳本實(shí)現(xiàn)部分

最重要的:

//載入素材圖  
 ScreenWaterDropTex = Resources.Load("ScreenWaterDrop") asTexture2D;  

源碼:

//-----------------------------------------------【C#腳本說(shuō)明】--------------------------
//  屏幕水幕特效的實(shí)現(xiàn)代碼-C#腳本部分  
//--------------------------------------------------------------------------------------------

using UnityEngine;  
using System.Collections;  

[ExecuteInEditMode]  
[AddComponentMenu("Shader/ScreenWaterDropEffect")]  
public class ScreenWaterDropEffect : MonoBehaviour  
{  
    //-------------------變量聲明部分-------------------  
    #region Variables  

    //著色器和材質(zhì)實(shí)例  
    public Shader CurShader;//著色器實(shí)例  
    private Material CurMaterial;//當(dāng)前的材質(zhì)  

    //時(shí)間變量和素材圖的定義  
    private float TimeX = 1.0f;//時(shí)間變量  
    private Texture2D ScreenWaterDropTex;//屏幕水滴的素材圖  

    //可以在編輯器中調(diào)整的參數(shù)值  
    [Range(5, 64), Tooltip("溶解度")]  
    public float Distortion = 8.0f;  
    [Range(0, 7), Tooltip("水滴在X坐標(biāo)上的尺寸")]  
    public float SizeX = 1f;  
    [Range(0, 7), Tooltip("水滴在Y坐標(biāo)上的尺寸")]  
    public float SizeY = 0.5f;  
    [Range(0, 10), Tooltip("水滴的流動(dòng)速度")]  
    public float DropSpeed = 3.6f;  

    //用于參數(shù)調(diào)節(jié)的中間變量  
    public static float ChangeDistortion;  
    public static float ChangeSizeX;  
    public static float ChangeSizeY;  
    public static float ChangeDropSpeed;  
    #endregion  

    //-------------------------材質(zhì)的get&set----------------------------  
    #region MaterialGetAndSet  
    Material material  
    {  
        get  
        {  
            if (CurMaterial == null)  
            {  
                CurMaterial = new Material(CurShader);  
                CurMaterial.hideFlags = HideFlags.HideAndDontSave;  
            }  
            return CurMaterial;  
        }  
    }  
    #endregion  

    //-----------------------------------------【Start()函數(shù)】-------------------------------
    // 說(shuō)明:此函數(shù)僅在Update函數(shù)第一次被調(diào)用前被調(diào)用  
    //-----------------------------------------------------------------------------------------
    void Start()  
    {  
        //依次賦值  
        ChangeDistortion = Distortion;  
        ChangeSizeX = SizeX;  
        ChangeSizeY = SizeY;  
        ChangeDropSpeed = DropSpeed;  

        //載入素材圖  
        ScreenWaterDropTex = Resources.Load("ScreenWaterDrop") as Texture2D;  

        //找到當(dāng)前的Shader文件  
        CurShader = Shader.Find("Shader/ScreenWaterDropEffect");  

        //判斷是否支持屏幕特效  
        if (!SystemInfo.supportsImageEffects)  
        {  
            enabled = false;  
            return;  
        }  
    }  

    //-------------------------------------【OnRenderImage()函數(shù)】--------------------- 
    // 說(shuō)明:此函數(shù)在當(dāng)完成所有渲染圖片后被調(diào)用,用來(lái)渲染圖片后期效果  
    //----------------------------------------------------------------------------------------- 
    void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)  
    {  
        //著色器實(shí)例不為空绰更,就進(jìn)行參數(shù)設(shè)置  
        if (CurShader != null)  
        {  
            //時(shí)間的變化  
            TimeX += Time.deltaTime;  
            //時(shí)間大于100瞧挤,便置0,保證可以循環(huán)  
            if (TimeX > 100) TimeX = 0;  

            //設(shè)置Shader中其他的外部變量  
            material.SetFloat("_CurTime", TimeX);  
            material.SetFloat("_Distortion", Distortion);  
            material.SetFloat("_SizeX", SizeX);  
            material.SetFloat("_SizeY", SizeY);  
            material.SetFloat("_DropSpeed", DropSpeed);  
            material.SetTexture("_ScreenWaterDropTex", ScreenWaterDropTex);  

            //拷貝源紋理到目標(biāo)渲染紋理儡湾,加上我們的材質(zhì)效果  
            Graphics.Blit(sourceTexture, destTexture, material);  
        }  
        //著色器實(shí)例為空特恬,直接拷貝屏幕上的效果。此情況下是沒(méi)有實(shí)現(xiàn)屏幕特效的  
        else  
        {  
            //直接拷貝源紋理到目標(biāo)渲染紋理  
            Graphics.Blit(sourceTexture, destTexture);  
        }  

    }  

    //-----------------------------------------【OnValidate()函數(shù)】----------------------- 
    // 說(shuō)明:此函數(shù)在編輯器中該腳本的某個(gè)值發(fā)生了改變后被調(diào)用  
    //-----------------------------------------------------------------------------------------
    void OnValidate()  
    {  
        ChangeDistortion = Distortion;  
        ChangeSizeX = SizeX;  
        ChangeSizeY = SizeY;  
        ChangeDropSpeed = DropSpeed;  
    }  

    //-----------------------------------------【Update()函數(shù)】----------------------------
    // 說(shuō)明:此函數(shù)在每一幀中都會(huì)被調(diào)用  
    //-----------------------------------------------------------------------------------------
    void Update()  
    {  
        //若程序在運(yùn)行徐钠,進(jìn)行賦值  
        if (Application.isPlaying)  
        {  
            //賦值  
            Distortion = ChangeDistortion;  
            SizeX = ChangeSizeX;  
            SizeY = ChangeSizeY;  
            DropSpeed = ChangeDropSpeed;  
        }  
        //找到對(duì)應(yīng)的Shader文件豺型,和紋理素材  
#if UNITY_EDITOR  
        if (Application.isPlaying != true)  
        {  
            CurShader = Shader.Find("Shader/ScreenWaterDropEffect");  
            ScreenWaterDropTex = Resources.Load("ScreenWaterDrop") as Texture2D;  

        }  
#endif  

    }  

    //-----------------------------------------【OnDisable()函數(shù)】-------------------------
    // 說(shuō)明:當(dāng)對(duì)象變?yōu)椴豢捎没蚍羌せ顮顟B(tài)時(shí)此函數(shù)便被調(diào)用    
    //-----------------------------------------------------------------------------------------
    void OnDisable()  
    {  
        if (CurMaterial)  
        {  
            //立即銷毀材質(zhì)實(shí)例  
            DestroyImmediate(CurMaterial);  
        }  

    }  
}   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末构韵,一起剝皮案震驚了整個(gè)濱河市毡庆,隨后出現(xiàn)的幾起案子吃媒,更是在濱河造成了極大的恐慌,老刑警劉巖爹袁,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件远荠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡失息,警方通過(guò)查閱死者的電腦和手機(jī)譬淳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)盹兢,“玉大人邻梆,你說(shuō)我怎么就攤上這事∫锩耄” “怎么了浦妄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我剂娄,道長(zhǎng)窘问,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任宜咒,我火速辦了婚禮,結(jié)果婚禮上把鉴,老公的妹妹穿的比我還像新娘故黑。我一直安慰自己,他們只是感情好庭砍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布场晶。 她就那樣靜靜地躺著,像睡著了一般怠缸。 火紅的嫁衣襯著肌膚如雪诗轻。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天揭北,我揣著相機(jī)與錄音扳炬,去河邊找鬼。 笑死搔体,一個(gè)胖子當(dāng)著我的面吹牛恨樟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疚俱,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼劝术,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了呆奕?” 一聲冷哼從身側(cè)響起养晋,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梁钾,沒(méi)想到半個(gè)月后绳泉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陈轿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年圈纺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片麦射。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛾娶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潜秋,到底是詐尸還是另有隱情蛔琅,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布峻呛,位于F島的核電站罗售,受9級(jí)特大地震影響辜窑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜寨躁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一穆碎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧职恳,春花似錦所禀、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至操禀,卻和暖如春褂策,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颓屑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工斤寂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人邢锯。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓扬蕊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親丹擎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尾抑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容