当前位置:   article > 正文

Unity-Shader - 2DSprite描边效果_unity shader sprite

unity shader sprite

实现一个简单的2D精灵图描边效果,效果如下
在这里插入图片描述
实现思路:
可以通过判断该像素周围是否有透明度为 0的值,如果有,则说明该像素位于边缘。
所以我们需要打开alpha blend,即: Blend SrcAlpha OneMinusSrcAlpha,并且加入渲染队列,

Tags{
     "Queue" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
  • 1
  • 2
  • 3
  • 4

根据图片的Alpha值边缘判定,向内扩一段距离做边缘,颜色设置为描边颜色;
片元着色阶段,向上下左右四个方向做检测,有一个点的透明度为0,判定为边缘;

fixed4 frag(v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
				// 采样周围4个点
				float2 up_uv = i.uv + float2(0, 1) * _LineWidth * 1 / 10 * _MainTex_ST.xy;
				float2 down_uv = i.uv + float2(0,-1) * _LineWidth * 1 / 10 * _MainTex_ST.xy;
				float2 left_uv = i.uv + float2(-1,0) * _LineWidth * 1 / 10 * _MainTex_ST.xy;
				float2 right_uv = i.uv + float2(1,0) * _LineWidth * 1 / 10 * _MainTex_ST.xy;
				// 如果有一个点透明度为0 说明是边缘
				float w = tex2D(_MainTex,up_uv).a * tex2D(_MainTex,down_uv).a * tex2D(_MainTex,left_uv).a * tex2D(_MainTex,right_uv).a;

				if (w == 0) {
					col.rgb = lerp(_LineColor * _Intensity, col.rgb, w);
				}

				return col;
			}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

如果图片内容恰好铺满整张图,没有alpha值,方法不适用

outline

可以和原图做插值,根据边缘判断来混合线的颜色和原图颜色
完整shader如下

Shader "shader2D/outline"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}  // 主纹理属性,用于存储2D纹理
        _lineWidth("lineWidth",Range(0,10)) = 1  // 线宽属性,范围在0到10之间,默认值为1
        _lineColor("lineColor",Color)=(1,1,1,1)  // 线的颜色属性,RGBA格式,默认为白色
    }
    SubShader
    {
        // 渲染队列采用透明
        Tags{
            "Queue" = "Transparent"
        }
        Blend SrcAlpha OneMinusSrcAlpha  // 设置混合模式为源颜色乘以源透明度减去源透明度

        Pass
        {
            CGPROGRAM
            #pragma vertex vert  
            #pragma fragment frag  

            #include "UnityCG.cginc"  

            // 顶点着色器输入结构体 
            struct VertexInput
            {
                float4 vertex : POSITION;  // 顶点坐标
                float2 uv : TEXCOORD0;  // 纹理坐标
            };

            // 顶点着色器输出结构体 
            struct VertexOutput
            {
                float2 uv : TEXCOORD0;  // 纹理坐标
                float4 vertex : SV_POSITION;  // 顶点坐标
            };

           
            VertexOutput vert (VertexInput v)
            {
                VertexOutput o;
                o.vertex = UnityObjectToClipPos(v.vertex);  // 将顶点坐标转换到裁剪空间
                o.uv = v.uv;  // 传递纹理坐标
                return o;
            }

            sampler2D _MainTex;  // 主纹理
            float4 _MainTex_TexelSize;  // 主纹理的像素大小
            float _lineWidth;  // 线宽
            float4 _lineColor;  // 线的颜色

            fixed4 frag (VertexOutput i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);  // 获取纹理颜色

                // 采样周围4个点
                float2 up_uv = i.uv + float2(0,1) * _lineWidth * _MainTex_TexelSize.xy;
                float2 down_uv = i.uv + float2(0,-1) * _lineWidth * _MainTex_TexelSize.xy;
                float2 left_uv = i.uv + float2(-1,0) * _lineWidth * _MainTex_TexelSize.xy;
                float2 right_uv = i.uv + float2(1,0) * _lineWidth * _MainTex_TexelSize.xy;

                // 如果有一个点透明度为0,说明是边缘
                float w = tex2D(_MainTex,up_uv).a * tex2D(_MainTex,down_uv).a * tex2D(_MainTex,left_uv).a * tex2D(_MainTex,right_uv).a;

                // 和原图做插值,根据边缘判断来混合线的颜色和原图颜色
                col.rgb = lerp(_lineColor,col.rgb,w);

                return col;
            }
            ENDCG
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/106605
推荐阅读
相关标签
  

闽ICP备14008679号