天天看点

shader编程学习(3)溶解

shader代码

Shader "Custom/zxtest"
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _NoiseTex ("NoiseTex (R)",2D) = "white"{} //辅助图片
        _DissolveSpeed ("DissolveSpeed (Second)",Float) = 1//溶解时间
        _EdgeWidth("EdgeWidth",Range(0,0.5)) = 0.1//溶解边缘的宽度,比如纸片燃烧时边缘变黑
        _EdgeColor("EdgeColor",Color) =  (1,1,1,1)//边缘的颜色
    }
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        
        Pass
        {
            CGPROGRAM
            #pragma vertex vert_img//顶点着色器 它会自动把结果返回到一个v2f_img结构体中
            #pragma fragment frag
            #include "UnityCG.cginc"
             
            uniform sampler2D _MainTex;
            uniform sampler2D _NoiseTex;
            uniform float _DissolveSpeed;
            uniform float _EdgeWidth;
            uniform float4 _EdgeColor;
            
			//v2f_img 自带的结构体 包含顶点坐标,和uv坐标
            float4 frag(v2f_img i):COLOR
            {
				//时间比例 0-1
				//unity给我们提供了几个不同的时间参数都保存在_Time中,其中_Time.y是标准的时间,单位(s)
                float DissolveFactor = saturate(_Time.y / _DissolveSpeed);
				//取得r值
                float noiseValue = tex2D(_NoiseTex,i.uv).r; 
				//如果r值小于时间比例
                if(noiseValue <= DissolveFactor)
                {
					//discard,是由CG提供的,若出现在fragmentShader中表示立即放弃当前处理的片元。
					//也就是说当我们判定当前片元需要溶解的时候我们就使用discard命令
                    discard;
                }
             
                float4 texColor = tex2D(_MainTex,i.uv);
				//EdgeFactor(0-1)越小表示越快要溶解,即越接近边缘
                float EdgeFactor = saturate((noiseValue - DissolveFactor)/(_EdgeWidth*DissolveFactor));
                float4 BlendColor = texColor * _EdgeColor;
                //lerp(x,y,a) = x*(1-a) + y*a; 越靠近边缘,颜色越接近定义的边缘颜色
                return lerp(texColor,BlendColor,1 - EdgeFactor);
            }
            
            ENDCG
        }
    } 
    
    FallBack Off
}
           

效果

shader编程学习(3)溶解
shader编程学习(3)溶解

继续阅读