上周分享了一个水墨风格的Shader,这周分享一个图片画点连线的Shader,话不多说,先看效果 我做的是一个百度人脸识别划线功能,图中所有蓝色的点都是通过百度人脸识别获取到的,要做的也只是把Vector4的数组传给Shader去处理
public Material material;
public List<Vector4> vector4s;
public BaiduTest baidu;
void Update()
{
if (Input.GetKeyDown(KeyCode.Z))
{
vector4s = baidu.allPoint;
material.SetVectorArray("_Vectors", vector4s);
material.SetInt("_VectorCount", vector4s.Count);
}
}
操作界面的基本属性
具体的Shader逻辑代码如下
Shader "Unlit/NewUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Distortion ("_Distortion", Range(0.0, 1.0)) = 0.3
_ScreenResolution ("_ScreenResolution", Vector) = (0.,0.,0.,0.)
_LP1("linePoint1",vector) = (300,100,0,0)
_LP2("linePoint2",vector) = (600,400,0,0)
_LineWidth("LineWidth",range(0,20)) = 10.0
_Point("LineWidth",range(0,100)) = 50.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
struct appdata
{
float4 vertex : POSITION;
};
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 texcoord : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
float4 _LP1;
float4 _LP2;
float _LineWidth;
float _Point;
half4 _MainTex_ST;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = UnityObjectToClipPos(IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color;
return OUT;
}
int _VectorCount = 0;
float4 _Vectors[1000];
fixed4 frag (v2f i) : SV_Target
{
for (int j=0;j<_VectorCount;j++)
{
if( pow((i.vertex.x- _Vectors[j].x ),2) + pow((i.vertex.y- _Vectors[j].y ),2) <_Point)
{
return fixed4(0,0,1,1);
}
}
int color=0;
for (int k=0;k<_VectorCount-1;k++)
{
_LP1 = _Vectors[k];
_LP2 = _Vectors[k+1];
if(_Vectors[k].x==0&&_Vectors[k].y==0&&_Vectors[k].z==0&&_Vectors[k].w==0)
{
continue;
}
if(_Vectors[k+1].x==0&&_Vectors[k+1].y==0&&_Vectors[k+1].z==0&&_Vectors[k+1].w==0)
{
continue;
}
float d = abs((_LP2.y-_LP1.y)*i.vertex.x + (_LP1.x - _LP2.x)*i.vertex.y +_LP2.x*_LP1.y -_LP2.y*_LP1.x )/sqrt(pow(_LP2.y-_LP1.y,2) + pow(_LP1.x-_LP2.x,2));
if(d<=_LineWidth/2)
{
float width = _LineWidth/2;
float xp=0;
if(_LP1.x < _LP2.x)
{
xp = clamp( i.vertex.x,_LP1.x-width , _LP2.x+width);
}
else
{
xp = clamp( i.vertex.x,_LP2.x- width, _LP1.x+width);
}
float yp=0;
if(_LP1.y < _LP2.y)
{
yp = clamp( i.vertex.y,_LP1.y- width, _LP2.y+width);
}
else
{
yp = clamp( i.vertex.y,_LP2.y- width , _LP1.y+width);
}
if(xp==i.vertex.x)
{
if(yp==i.vertex.y)
{
color=1;
break;
}
}
}
color=0;
continue;
}
if(color>0)
{
return fixed4(1,0,0,1);
}
else
{
fixed4 col= tex2D(_MainTex,i.texcoord);
return col;
}
}
ENDCG
}
}
}
Shader代码我大体写了注释,主要也就是关于点集合的操作,唯一需要注意的是,因为我传的是一个点的集合,所以线必然是重头连到尾的,所以每条线段的点集合我都加了一个Vector4.Zero,所以下面的操作是为了跳过连线(PS:因为fixed4类型是不能直接拿出做比较的,所以只能把每个数字依次拿出来做比较)
就这么多,用的自取,或者私信我要代码。码字不易,用的上给点个赞,多谢
|