边缘检测效果动画Shader实现

AR项目中在扫描识别图时需要加上扫描识别效果,加上边缘识别后看起来效果更好,所以就需要这样一个边缘检测效果的动画Shader。
Shader "Unlit/AnimateEdgeShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_EdgeOnly ("Edge Only",Range(0,1)) = 1
		_EdgeColor ("Edge Color",Color) = (1,0,0,1)
		_BackgroundColor ("Background Color",Color) = (1,1,1,1)

		_AnimateTex ("Texture", 2D) = "white" {}
		_ScrollX ("Speed",Float) = 0.5
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100
		Blend SrcAlpha OneMinusSrcAlpha

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

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

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

			sampler2D _MainTex;
			float4 _MainTex_ST;

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);

				return o;
			}

			fixed4 frag (v2f i) : SV_Target
			{
				return tex2D(_MainTex, i.uv);
			}
			ENDCG

		}

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

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

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

			sampler2D _AnimateTex;
			float4 _AnimateTex_ST;
			float _ScrollX;

			sampler2D _MainTex;
			half4 _MainTex_TexelSize;
			float4 _MainTex_ST;
			fixed _EdgeOnly;
			fixed4 _EdgeColor;
			fixed4 _BackgroundColor;

			fixed luminance(fixed4 color)
			{
				return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;
			}

			half Sobel(v2f i)
			{
				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;
			}
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				
				o.uv[0] = v.uv + _MainTex_TexelSize.xy * half2(-1,-1);
				o.uv[1] = v.uv + _MainTex_TexelSize.xy * half2(0,-1);
				o.uv[2] = v.uv + _MainTex_TexelSize.xy * half2(1,-1);
				o.uv[3] = v.uv + _MainTex_TexelSize.xy * half2(-1,0);
				o.uv[4] = v.uv + _MainTex_TexelSize.xy * half2(0,0);
				o.uv[5] = v.uv + _MainTex_TexelSize.xy * half2(1,0);
				o.uv[6] = v.uv + _MainTex_TexelSize.xy * half2(-1,1);
				o.uv[7] = v.uv + _MainTex_TexelSize.xy * half2(0,1);
				o.uv[8] = v.uv + _MainTex_TexelSize.xy * half2(1,1);

				o.uv[4] = TRANSFORM_TEX(v.uv, _AnimateTex) + frac(float2(0.0,-_ScrollX) * _Time.y);


				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
			
				half edge = Sobel(i);

				fixed4 withEdgeColor = lerp(_EdgeColor,tex2D(_MainTex, i.uv[4]),edge);
				fixed4 onlyEdgeColor = lerp(_EdgeColor,_BackgroundColor,edge);

				fixed4 finalColor = lerp(withEdgeColor,onlyEdgeColor,_EdgeOnly);

				fixed4 col = tex2D(_AnimateTex, i.uv[4]);

				return fixed4(finalColor.rgb,(finalColor.a * (1.0 - col.r)));
			}
			ENDCG
		}
	}
}

这里用Easy AR 实验效果。调用摄像机,显示画面,并描绘边框


这里的第二个材质球RealityPlane就是 Easy AR实时获取的手机摄像机画面,第一个材质球就是我们的边缘检测Shader,Animate第一张图片显示我们要检测边缘的图片,第二张图片就是我们边框描绘的图片。

边框图片大概就这样,可以自己调整


效果就是这样




 
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值