Unity菜鸟开发纪要——2D描边

3D模型的描边漫天飞,通过法线计算就行,但是2D还是虽然也有,但不是自己想要的,毕竟只是想调一下颜色,阈值,边缘大小就行。

之前是做图像处理的,用的波门处理,计算一个像素点与周围的梯度值差异,大于阈值的就是边缘点。求的边缘点与边缘色混合,再与原色混合输出就可以。直接上代码:

在这里插入代码片
Shader "UIEffect/Outline" {
	Properties {
		// [NoScaleOffset] _MainTex ("Main Texture", 2D) = "black" {}

		 _OutlineWidth("Outline Width", Range(0, 10)) = 3.0
		 _OutlineColor("Outline Color", Color) = (1,1,0,1)
		 _ThresholdEnd("Outline Threshold", Range(0, 1)) = 0.25
		 _OutlineSmoothness("Outline Smoothness", Range(0, 1)) = 1.0
	}

	SubShader {
		Tags { 	"Queue"="Transparent" 
				"IgnoreProjector"="True" 
				"RenderType"="Transparent" 
		}

		Cull Off
		ZWrite Off
		Lighting Off
		Blend One OneMinusSrcAlpha
		


		Pass {
			Name "Outline"
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"


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

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

            v2f vert (appdata v)
            {
                v2f o = (v2f)0;
                o.uv = v.uv;
                o.vertex = UnityObjectToClipPos(v.vertex);
				o.vertexAlpha = v.color.a;
                return o;
            }

            sampler2D _MainTex;
			float _OutlineWidth;
			float4 _OutlineColor;
			float4 _MainTex_TexelSize;
			float _ThresholdEnd;
			float _OutlineSmoothness;

            fixed4 frag (v2f i) : SV_Target
            {
               	float4 mainCol = tex2D(_MainTex, i.uv);
				// 使用自己的alpha数值, 不然计算之后的颜色的alpha值也会加进来
				mainCol.rgb *= mainCol.a;

				// 计算中心像素的alpha ,通过比较周围4个像素点的alpha,判断是不是边缘点
				float xOffset = _MainTex_TexelSize.x * _OutlineWidth / (1024 * _MainTex_TexelSize.x);
				float yOffset = _MainTex_TexelSize.y * _OutlineWidth / (1024 * _MainTex_TexelSize.x);


				float pixelCenter = tex2D(_MainTex, i.uv).a;

				float4 centerLod = float4(i.uv, 0, 0);
				float pixelTop = tex2Dlod(_MainTex, centerLod + float4(0,  yOffset, 0, 0)).a;
				float pixelBottom = tex2Dlod(_MainTex, centerLod + float4(0, -yOffset, 0, 0)).a;
				float pixelLeft = tex2Dlod(_MainTex, centerLod + float4(-xOffset, 0, 0, 0)).a;
				float pixelRight = tex2Dlod(_MainTex, centerLod + float4(xOffset, 0, 0, 0)).a;

				float numSamples = 1;
				float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * i.vertexAlpha / numSamples;


				float thresholdStart = _ThresholdEnd * (1.0 - _OutlineSmoothness);
				float outlineAlpha = saturate((average - thresholdStart) / (_ThresholdEnd - thresholdStart)) - pixelCenter;
				mainCol.rgba = lerp(mainCol, _OutlineColor, outlineAlpha);

				return mainCol;
            }
			ENDCG
		}

	}
	
}

效果图不贴了,不会粘贴,直接复制代码就能使用。创建一个材质球,材质球放在Image组件的material里面即可。想要发光效果的,需要对边缘色模糊处理,就是2D的边缘泛光。

猜你喜欢

转载自blog.csdn.net/qq_36460731/article/details/104677469