屏幕后处理-边缘检测-描边效果-实例
using UnityEngine;

public class Bianyuan : MonoBehaviour
{
    public Material mat;

    public Color edgeColor = Color.black; //描边的颜色

    private void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (mat != null)
        {
            mat.SetColor("_EdgeColor", edgeColor);

            Graphics.Blit(source, destination, mat);
        }
    }
}


Shader "Unlit/bianyuan"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_EdgeColor("Edge Color",Color) = (0,0,0,1)
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			ZTest Always Cull Off ZWrite Off

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

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

			sampler2D _MainTex;
			float4 _MainTex_TexelSize;//纹理每个纹素的大小,例如512*512,那就是1/512
			fixed4 _EdgeColor; 
			
			v2f vert (appdata_img v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);

				half2 uv = v.texcoord;

				//计算出当前像素附近的8个像素点,在顶点处理后会经过插值到片元(线性操作),不影响
				o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1);
				o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1);
				o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1);
				o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0);
				o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0);
				o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0);
				o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1);
				o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1);
				o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1);

				return o;
			}
			
			//计算出梯度值,越小表示和附近像素颜色相差越大,边缘可能性大
			half Sobel(v2f i) 
			{ 
				//Sobel边缘检测算子 卷积核
				const half Gx[9] = { -1, -2, -1,                        
									 0,  0,  0,                        
									 1,  2,  1 };    
				const half Gy[9] = { -1,  0,  1,                        
									 -2,  0,  2,                        
									 -1,  0,  1 };    
				half texColor;    
				half edgeX = 0;    
				half edgeY = 0;    
				for (int it = 0; it < 9; it++) 
				{ 
					texColor = Luminance(tex2D(_MainTex, i.uv[it]));        
					edgeX += texColor * Gx[it];        
					edgeY += texColor * Gy[it]; 
				}    
				half edge = 1 - abs(edgeX) - abs(edgeY);  
				return edge; 
			}

			fixed4 frag (v2f i) : SV_Target
			{
				half edge = Sobel(i);
				
				//根据梯度值,看看是否使用的边缘颜色
				fixed4 withEdgeColor = lerp(_EdgeColor, tex2D(_MainTex, i.uv[4]), edge);

				return withEdgeColor;
			}
			ENDCG
		}
	}

	Fallback Off
}


常用的边缘检测算子


blob.png

blob.png


首页 我的博客
粤ICP备17103704号