图片内发光

作者:追风剑情 发布于:2019-1-27 14:55 分类:Shader

一、工程截图

2222.png

二、Shader代码


Shader "Custom/Glow"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _GlowColor ("Glow Color", Color) = (0, 1, 0, 1)
        _GlowSize ("Glow Size", Range(0.01, 1)) = 0.2
         //图片高宽比
        _AspectRatio ("Aspect Ratio", Float) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _GlowColor;
            half _GlowSize;
            fixed _AspectRatio;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                fixed center = 0.5;
                //平移原点到图片中心
                fixed2 uv = i.uv - fixed2(center, center);
                uv.x = abs(uv.x);
                uv.y = abs(uv.y);

                fixed glowSizeX = _GlowSize * _AspectRatio;
                fixed glowSizeY = _GlowSize;

                //内矩形最大角
                fixed2 innerMax = fixed2(center-glowSizeX, center-glowSizeY);

                //普通版代码
                /* if (uv.x >= innerMax.x || uv.y >= innerMax.y)
                {
                    fixed t = 0;
                    if (uv.x > innerMax.x && uv.y > innerMax.y) {
                        if ((uv.x -  innerMax.x)/_AspectRatio > uv.y - innerMax.y) {
                            t = (uv.x - innerMax.x)/glowSizeX;
                        }else{
                            t = (uv.y - innerMax.y)/glowSizeY;
                        }
                    }else if(uv.x >= innerMax.x) {
                        t = (uv.x - innerMax.x)/glowSizeX;
                    }else if(uv.y >= innerMax.y) {
                        t = (uv.y - innerMax.y)/glowSizeY;
                    }
                    return col*(1-t) + _GlowColor*t;
                } */

                //优化后的代码(即,对上面版本的代码消除流程控制)
                fixed margin = max(step(innerMax.x, uv.x), step(innerMax.y, uv.y));
                fixed t = 0;
                fixed tx = (uv.x - innerMax.x)/glowSizeX;
                fixed ty = (uv.y - innerMax.y)/glowSizeY;

                fixed innerCorner = step(innerMax.x, uv.x) * step(innerMax.y, uv.y);
                fixed leftRight = step(innerMax.x, uv.x);
                fixed topBottom = step(innerMax.y, uv.y);
                fixed nearX = step(uv.y - innerMax.y, (uv.x -  innerMax.x)/_AspectRatio);

                fixed tc = tx * nearX + ty * (1 - nearX);//当uv坐标落在四个角时的插值t
                t = tc * innerCorner + tx * (1-innerCorner) * leftRight + ty * (1-innerCorner) * topBottom;

                col = col * (1-margin) + (col*(1-t) + _GlowColor*t) * margin;
                return col;
            }
            ENDCG
        }
    }
}


效果, 通过调整GlowSize值来调整发光边缘大小

1.gif

标签: Shader

Powered by emlog  蜀ICP备18021003号   sitemap

川公网安备 51019002001593号