美文网首页
Unity Shader 极简实践4——图片外发光

Unity Shader 极简实践4——图片外发光

作者: 太刀 | 来源:发表于2021-03-07 10:25 被阅读0次
    《风暴英雄》Nora

    0.本文示例代码地址

    GitHub

    3D模型的外放光效果相对来说容易实现一些。这篇文章描述了如何实现2D图片的外发光效果。
    思路:在片元着色器中,进行一个“模糊”操作。针对当前像素 p 进行纹理采样,并做判断:

    • 若采样结果 alpha 值为0,则 p 为透明像素,此时根据一个制定长度的“十字格”来取 p 周围像素的 alpha 值并进行平均,得到 p 的 alpha 值,rgb 值为参数设置的外发光颜色值。
    • 若采样结果 alpha 非 0,则p非透明像素,直接返回采样结果颜色。
      代码如下:
    Shader "Custom_Shader/Outlight"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _LightColor ("Light Color", Color) = (1.0, 1.0, 1.0, 1.0)
            _Size ("Size", Int) = 1 
        }
    
        SubShader {
    
            Blend SrcAlpha OneMinusSrcAlpha
    
            CGINCLUDE
            #include "UnityCG.cginc"
    
            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv: TEXCOORD0;
            };
    
            sampler2D _MainTex;
            float4 _MainTex_ST;
            half4 _MainTex_TexelSize;
            float4 _LightColor;
            int _Size;
    
            ENDCG
    
            Pass {
    
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
    
                v2f vert(appdata_img IN)
                {
                    v2f OUT;
                    OUT.pos = UnityObjectToClipPos(IN.vertex);
                    OUT.uv = TRANSFORM_TEX(IN.texcoord, _MainTex);
                    return OUT;
                }
    
                fixed4 frag(v2f IN) : SV_Target
                {
                    fixed4 color = tex2D(_MainTex, IN.uv);
                    fixed4 c = _LightColor;
                    float sum = tex2D(_MainTex, IN.uv).a;
                    for (int i = 1; i <= _Size; i ++) {
                        sum += tex2D(_MainTex, IN.uv + _MainTex_TexelSize.xy * half2(i, 0)).a;
                        sum += tex2D(_MainTex, IN.uv + _MainTex_TexelSize.xy * half2(-1 * i, 0)).a;
                        sum += tex2D(_MainTex, IN.uv + _MainTex_TexelSize.xy * half2(0, 1 * i)).a;
                        sum += tex2D(_MainTex, IN.uv + _MainTex_TexelSize.xy * half2(0, -1 * i)).a;
                    }
    
                    c.a = sum / (4 * _Size + 1);
    
                    return step(0.1, color.a) * color + step(0.1, 1-color.a) * c;
                }
    
                ENDCG
            }
        } 
    }
    

    效果:


    外发光

    这个方法在某些特殊的像素处理效果不太好,比如图中刀尖的部分,可以考虑将“模糊核”由十字格改成“圆形”来进行模糊,效果会好一些
    将上面代码中的片段着色器改成如下代码

                fixed4 frag2(v2f IN) : SV_TARGET
                {
                    fixed4 color = tex2D(_MainTex, IN.uv);
                    fixed4 c = _LightColor;
                    float sum = tex2D(_MainTex, IN.uv).a;
                    for (int i = -_Size ; i <= _Size; i ++) {
                        for (int j = -_Size; j <= _Size; j ++) {
                            if (abs(i) != abs(j))
                            {
                                sum += tex2D(_MainTex, IN.uv + _MainTex_TexelSize.xy * half2(i, j)).a;
                            }       
                        }
                    }
    
                    c.a = sum / (_Size * _Size * 2);
    
                    return step(0.1, color.a) * color + step(0.1, 1-color.a) * c;
                }
    

    得到效果


    外发光优化

    相关文章

      网友评论

          本文标题:Unity Shader 极简实践4——图片外发光

          本文链接:https://www.haomeiwen.com/subject/cwjntltx.html