zoukankan      html  css  js  c++  java
  • LOGO闪光效果

    原地址:http://cl314413.blog.163.com/blog/static/1905079762014122105235138/

    【风宇冲】Unity3D教程宝典之Shader篇:第五讲LOGO闪光效果

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




    【风宇冲】Unity3D教程宝典之Shader篇:第五讲LOGO闪光效果
    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
            }
        }
    }
    转载自风宇冲Unity3D教程学院

  • 相关阅读:
    hdu 4614 线段树 二分
    cf 1066d 思维 二分
    lca 最大生成树 逆向思维 2018 徐州赛区网络预赛j
    rmq学习
    hdu 5692 dfs序 线段树
    dfs序介绍
    poj 3321 dfs序 树状数组 前向星
    cf 1060d 思维贪心
    【PAT甲级】1126 Eulerian Path (25分)
    【PAT甲级】1125 Chain the Ropes (25分)
  • 原文地址:https://www.cnblogs.com/123ing/p/3767159.html
Copyright © 2011-2022 走看看