unity 实现遮罩效果

xiaoxiao2021-02-28  92

  这个效果在很多LOGO及广告宣传中都会用到。商业开发的做法应该是拿一张闪光的图,对其做uv移动,然后和原图两张图混合,这样运算会小很多,需要储存的变量也会小很多。本讲不用图而完全通过计算得出闪光区域,主要是借此加深uv计算实现特殊效果的实现,以及计算uv的方法。代码注释配合图解已经比较详细了,跟着做就行,随便找一张半透明的图来做底图即可。

http://www.xuebuyuan.com/2959899.html

Shader "Custom/LogoShader" {    Properties {        _MainTex ("Texture"2D) = "white" { }    }     SubShader    {    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}   Blend SrcAlpha OneMinusSrcAlpha         AlphaTest Greater 0.1        pass        {             CGPROGRAM            #pragma vertex vert            #pragma fragment frag            #include "UnityCG.cginc"                    sampler2D _MainTex;            float4 _MainTex_ST;                       struct v2f {                float4  pos : SV_POSITION;                float2  uv : TEXCOORD0;            };                       //顶点函数没什么特别的,和常规一样            v2f vert (appdata_base v)            {                v2f o;                   o.pos = mul(UNITY_MATRIX_MVP,v.vertex);                o.uv =    TRANSFORM_TEX(v.texcoord,_MainTex);                return o;            }                       //必须放在使用其的 frag函数之前,否则无法识别。            //核心:计算函数,角度,uv,光带的x长度,间隔,开始时间,偏移,单次循环时间            float inFlash(float angle,float2 uv,float xLength,int interval,int beginTimefloat offXfloat loopTime )            {                //亮度值                float brightness =0;                               //倾斜角                float angleInRad = 0.0174444 * angle;                               //当前时间                float currentTime = _Time.y;                           //获取本次光照的起始时间                int currentTimeInt = _Time.y/interval;                currentTimeInt *=interval;                               //获取本次光照的流逝时间 = 当前时间 - 起始时间                float currentTimePassed = currentTime -currentTimeInt;                if(currentTimePassed >beginTime)                {                    //底部左边界和右边界                    float xBottomLeftBound;                    float xBottomRightBound;                     //此点边界                    float xPointLeftBound;                    float xPointRightBound;                                       float x0 = currentTimePassed-beginTime;                    x0 /= loopTime;                               //设置右边界                    xBottomRightBound = x0;                                       //设置左边界                    xBottomLeftBound = x0 - xLength;                                       //投影至x的长度 = ytan(angle)                    float xProjL;                    xProjL= (uv.y)/tan(angleInRad);                     //此点的左边界 = 底部左边界 - 投影至x的长度                    xPointLeftBound = xBottomLeftBound - xProjL;                    //此点的右边界 = 底部右边界 - 投影至x的长度                    xPointRightBound = xBottomRightBound - xProjL;                                       //边界加上一个偏移                    xPointLeftBound += offX;                    xPointRightBound += offX;                                       //如果该点在区域内                    if(uv.x > xPointLeftBound && uv.x < xPointRightBound)                    {                        //得到发光区域的中心点                        float midness = (xPointLeftBound + xPointRightBound)/2;                                               //趋近中心点的程度,0表示位于边缘,1表示位于中心点                        float rate= (xLength -2*abs(uv.x - midness))/ (xLength);                        brightness = rate;                    }                }                brightnessmax(brightness,0);                               //返回颜色 = 纯白色 * 亮度                float4 col = float4(1,1,1,1) *brightness;                return brightness;            }                       float4 frag (v2f i) : COLOR            {                 float4 outp;                                 //根据uv取得纹理颜色,和常规一样                float4 texCol = tex2D(_MainTex,i.uv);                        //传进i.uv等参数,得到亮度值                float tmpBrightness;                tmpBrightness =inFlash(75,i.uv,0.25f,5f,2f,0.15,0.7f);                           //图像区域,判定设置为 颜色的A > 0.5,输出为材质颜色+光亮值                if(texCol.w >0.5)                        outp  =texCol+float4(1,1,1,1)*tmpBrightness;                //空白区域,判定设置为 颜色的A <=0.5,输出空白                else                    outp =float4(0,0,0,0);                 return outp;            }            ENDCG        }     } }
转载请注明原文地址: https://www.6miu.com/read-46316.html

最新回复(0)