zoukankan      html  css  js  c++  java
  • Unity3D教程宝典之Shader篇:第五讲LOGO闪光效果

                             

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

     


     
     
    Shader "Custom/logo" {
        Properties {
            _MainTex ("Texture", 2D) = "white" { }
        }
        SubShader
        {
            AlphaTest Greater .2
            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 beginTime, float offX, float 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的长度 = y/ tan(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;
                        }
                    }
                    brightness= max(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
            }
        }
    }
    

      

  • 相关阅读:
    xapian的使用
    Andriod 环境配置以及第一个Android Application Project
    2013Esri全球用户大会之ArcGIS for Server&Portal for ArcGIS
    window server 2012 更改密钥 更改系统序列号
    持续集成之路——数据访问层的单元测试(续)
    多项式相乘与相加演示
    hdu 1847 博弈基础题 SG函数 或者规律2种方法
    solaris之cpu
    Android音效SoundPool问题:soundpool 1 not retry
    poj1845-Sumdiv
  • 原文地址:https://www.cnblogs.com/zdlbbg/p/4329108.html
Copyright © 2011-2022 走看看