首页 > 代码库 > 【OpenGL】Shader实例分析(六)- 卡牌特效

【OpenGL】Shader实例分析(六)- 卡牌特效

转发请保持地址:http://blog.csdn.net/stalendp/article/details/30989295

本文将介绍怎么通过alpha通道来隐藏信息,并实现卡牌特效。运行效果如下:


代码如下:

Shader "stalendp/imageShine" {
	Properties {
		_MainTex ("image", 2D) = "white" {}
		_NoiseTex("noise", 2D) = "bump" {}
		_percent("percent", Range(-0.3, 1)) = 0
		_DefColor ("defalutColor", COLOR)  = ( 0, .8, .4, 1)
	}
	
	CGINCLUDE
        #include "UnityCG.cginc"           
      
        sampler2D _MainTex;
        sampler2D _NoiseTex;		
		float _percent;
		fixed4 _DefColor;
		
        struct v2f {    
            half4 pos:SV_POSITION;    
            half4 uv : TEXCOORD0;   
        };  
  
        v2f vert(appdata_full v) {  
            v2f o;  
            o.pos = mul (UNITY_MATRIX_MVP, v.vertex);  
            o.uv.xy = v.texcoord.xy;
            o.uv.zw = v.texcoord.xy + _Time.xx ;
            return o;  
        }  
  
        fixed4 frag(v2f i) : COLOR0 {
     		// 原始卡牌, 把alpha设置为1,屏蔽掉alpha通道信息
			fixed4 tex0 = tex2D(_MainTex, i.uv.xy);
			tex0.a = 1;
			// 透明躁动卡牌; 使用alpha通道信息,设置显示颜色,并加入躁动;
			half3 noise = tex2D(_NoiseTex, i.uv.zw );
			fixed4 tex1 = tex2D(_MainTex, i.uv.xy + noise.xy * 0.05 - 0.025);
			tex1.rgb = _DefColor.rgb;
			
            return lerp(tex0, tex1, smoothstep(0, 0.3, i.uv.y-_percent));
        }  
    ENDCG    
  
    SubShader {   
        Tags {"Queue" = "Transparent"}     
        ZWrite Off     
        Blend SrcAlpha OneMinusSrcAlpha     
        Pass {    
            CGPROGRAM    
            #pragma vertex vert    
            #pragma fragment frag    
            #pragma fragmentoption ARB_precision_hint_fastest     
  
            ENDCG    
        }
    }
    FallBack Off  
}

素材准备:

1)在本例中,在photoshop中处理图片,在alpha通道中存放了如下的信息图:


然后导出图片成为 tif格式。

2)准备一张噪声图片,并在unity下转化为Normal Map类型。如下图:


3)用Quad来测试当前shader。填写shader参数如下:


调节percent,就可以看到文章开头的那个特效。

原理解析:

1)透明躁动图片,这是在alpha图片的基础上加入躁动得到的结果。代码如下:
half3 noise = tex2D(_NoiseTex, i.uv.zw );
fixed4 tex1 = tex2D(_MainTex, i.uv.xy + noise.xy * 0.05 - 0.025);
tex1.rgb = _DefColor.rgb;
2)两个图片的叠加;通过比较uv中的v 和 _percent,来融合处理后的alpha通道和rgb通道。
lerp(tex0, tex1, smoothstep(0, 0.3, i.uv.y-_percent));

延伸:

当然也可以只对图片的局部进行处理。比如下图对闪电的处理,把闪电信息存放到alpha通道,然后就可以在shader做相应的处理了:


本文主要介绍怎样利用图片的alpha通道来隐藏信息,可以节省资源。这样的运用会有很多,有机会以后多加介绍。