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第一張圖片顯示我們要檢測邊緣的圖片,第二張圖片就是我們邊框描繪的圖片。
邊框圖片大概就這樣,可以自己調整
效果就是這樣