zoukankan      html  css  js  c++  java
  • 扫描shader

    游戏中经常需要制作出白光扫描的效果,这道光在透明区域不会显示。如果用图片叠加可能透明区域不太好处理,这里可通过shader实现。

    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 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
            }
        }
    }

    运行效果:

  • 相关阅读:
    Kubernetes-Pod的扩、缩容以及滚动升级
    从一个例子开始认识Kubernetes
    Kubernetes的基本术语和概念
    一分钟看懂Docker的网络模式和跨主机通信
    监控神器:Premotheus+Grafana安装
    Linux不同服务器之间copy文件
    Oracle 存储情况查询
    Kubernetes v1.10 快速安装(只需三步)
    django 搭建一个投票类网站(二)
    django 搭建一个投票类网站(一)
  • 原文地址:https://www.cnblogs.com/MiniHouse/p/5231516.html
Copyright © 2011-2022 走看看