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的边缘泛光。
来源:CSDN
作者:qq_36460731
链接:https://blog.csdn.net/qq_36460731/article/details/104677469