实现方式和原理参考这篇
![](https://i-blog.csdnimg.cn/blog_migrate/aa1208396dbfd1417d6daf6eb55d3b2d.png)
image.png
简单概况一下原理就是:获取当前顶点在屏幕的深度值z,如果跟场景中其他物体的深度z差距小于某个值则改变颜色。
最终效果:
![](https://i-blog.csdnimg.cn/blog_migrate/f894b88fc301f7fe1f2971e64775da8e.gif)
Mar-29-2021 13-19-05.gif
代码如下:
Shader "Custom/相交高亮"
{
Properties
{
_Color ("Main Tint", Color) = (1,1,1,1)
_Threshold ("Threshold", Range(0, 1)) = 1
_HighlightColor("HighlightColort", Color) = (1,1,1,1)
}
SubShader
{
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
Pass {
Tags { "LightMode"="ForwardBase" }
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
sampler2D _CameraDepthTexture;
fixed _Threshold;
fixed4 _HighlightColor;
struct a2v{
float4 vertex : POSITION;
};
struct v2f{
float4 pos : SV_POSITION;
float4 projPos : TEXCOORD0;
};
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos ( v.vertex );
//ComputeScreenPos传入Clip Space坐标pos, 最终输出xy在[0, 1]之间, z值为Camera Space深度的结果
o.projPos = ComputeScreenPos ( o.pos );
//计算eye space的深度值
o.projPos.z = COMPUTE_EYEDEPTH(o.projPos.z);
return o;
}
fixed4 frag(v2f i) : SV_Target {
//unity提供了内置的纹理_CameraDepthTexture存储的是屏幕深度信息
float sceneZ = LinearEyeDepth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
float partZ = i.projPos.z;
//如果两个顶点之间的Z值差小于_Threshold,则lerp颜色
float diff = min ( (abs(sceneZ - partZ)) / _Threshold, 1);
float4 finalColor = lerp(_HighlightColor, _Color, diff);
return finalColor;
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}