之前一直有人找我要EasyAR那种摄像头的扫描线效果shader,这个其实是我几年前写的,这里也懒得注释了,直接发出来分享给大家吧,做了一些过渡渐隐的效果。
效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/2a970051ef942a493086019a54275ab9.png)
image.png
shader代码:
Shader "Unlit/平面扫描"
{
Properties
{
_MainTex ("Main Tex", 2D) = "white" {}
_SacnLinePosition("扫描线位置",Range (0,1))=1
_SacnLineWidth("扫描线宽度",Range (0,0.1))=0.05
_StrokeRange("描边厚度",Range (0,0.2))=0.05
_StrokeColor ("描边颜色", Color) = (1, 1, 1, 1)
_SacnLineAlpha("扫描线淡度",Range (0,1))=1
jingdu("jingdu",Range (0.00000001,0.1))=0.001
}
SubShader
{
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True"}
Pass
{
Tags { "LightMode"="ForwardBase" }
ZTest off
ZWrite Off
Cull Off
Lighting Off
Fog { Mode Off }
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile DUMMY PIXELSNAP_ON
sampler2D _MainTex;
fixed3 _MaskColor;
float _StrokeRange;
fixed3 _ComparColor;
fixed4 _StrokeColor;
float _SacnLinePosition;
float _SacnLineWidth;
float _SacnLineAlpha;
float jingdu;
struct a2v
{
float4 vertex : POSITION;
float3 texcoord : TEXCOORD0;
};
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f vert (a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed r_abs;
fixed g_abs;
fixed b_abs;
fixed4 frag (v2f i) : SV_Target
{
fixed4 c = tex2D(_MainTex, i.uv);
if(i.uv.y>=_SacnLinePosition)
{
if(i.uv.y<=_SacnLinePosition+_SacnLineWidth)
c.rgb+=_SacnLineAlpha*0.1*_StrokeColor*(_SacnLinePosition+_SacnLineWidth-i.uv.y)/_SacnLineWidth;
_ComparColor=tex2D(_MainTex, i.uv+ float2(0,jingdu)).rgb;
r_abs=abs(c.r-_ComparColor.r);
g_abs=abs(c.g-_ComparColor.g);
b_abs=abs(c.b-_ComparColor.b);
if((r_abs>_StrokeRange&&g_abs>_StrokeRange)||(r_abs>_StrokeRange&&b_abs>_StrokeRange)||(b_abs>_StrokeRange&&b_abs>_StrokeRange))
{
c.rgb+=_SacnLineAlpha*_StrokeColor;
}
_ComparColor=tex2D(_MainTex, i.uv+ float2(jingdu,0)).rgb;
r_abs=abs(c.r-_ComparColor.r);
g_abs=abs(c.g-_ComparColor.g);
b_abs=abs(c.b-_ComparColor.b);
if((r_abs>_StrokeRange&&g_abs>_StrokeRange)||(r_abs>_StrokeRange&&b_abs>_StrokeRange)||(b_abs>_StrokeRange&&b_abs>_StrokeRange))
{
c.rgb+=_SacnLineAlpha*_StrokeColor;
}
}
return c;
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
c#控制脚本代码:
using UnityEngine;
using System.Collections;
public class LineScan : MonoBehaviour
{
public LineState LineState = new LineState ();
//扫描的速度
[Range (0.001f, 1)]
public float _showSpeed = 0.01f;
[Range (0.001f, 0.2f)]
public float _missSpeed=0.05f;
[Range (0.1f, 5f)]
public float IntervalTime=1f;
private MeshRenderer _render;
private void Awake ()
{
_render = GetComponent<MeshRenderer> ();
LineState = LineState.end;
SetX (1);
StartCoroutine (ChangeLineStateDown());
}
public void SetX (float val)
{
_render.material.SetFloat ("_SacnLinePosition", val);
}
public void Set_AlphaRange (float val)
{
_render.material.SetFloat ("_SacnLineAlpha", val);
}
public float deltaX = 1;
public float _AlphaRange=1;
void Update(){
switch (LineState) {
case LineState.down:
_AlphaRange = 1;
Set_AlphaRange (_AlphaRange);
if (deltaX > 0) {
deltaX = Mathf.Clamp01 (deltaX - _showSpeed);
SetX (deltaX);
} else {
deltaX = 1;
LineState = LineState.miss;
}
break;
case LineState.miss:
if (_AlphaRange > 0.01f) {
_AlphaRange = Mathf.Lerp (_AlphaRange ,0,_missSpeed);
Set_AlphaRange (_AlphaRange);
} else {
deltaX = 1;
LineState = LineState.end;
StartCoroutine (ChangeLineStateDown());
}
break;
case LineState.end:
break;
}
}
IEnumerator ChangeLineStateDown(){
yield return new WaitForSeconds (IntervalTime);
LineState = LineState.down;
}
}
public enum LineState
{
down,
miss,
end
}
包下载:链接: https://pan.baidu.com/s/1vlnljL32A8FezpnXrnTq7w 密码: cf22