Home>

### Unity Shader intersection algorithm realizes simple anti-energy shield

Unity shader learning:intersect algorithm to achieve a simple anti-energy shield

Main ideas:Comparing the depth difference between the object and the scene depth map in the observation space,The smaller the depth difference indicates the intersection,The darker the color,Add outline light to outline.

``````shader "unlit/depthoutline"
{
properties {
_maintex ("maintex", 2d)="white" {}
_rimfactor ("rimfactor", range (0.0,5.0))=1.0
_distancefactor ("distancefactor", range (0.0,10.0))=1.0
_rimcolor ("rimcolor", color)=(1,0,0,1)
_distancefactor2 ("distancefactor2", range (0.0,10.0))=1.0
_distancefactor3 ("distancefactor3", range (0.0,5.0))=1.0
}
tags {"queue"="transparent" "rendertype"="transparent" "ignoreprojector"="true"}
pass {
blend srcalpha oneminussrcalpha
zwrite off
cull off
cgprogram
#include "unitycg.cginc"
#pragma vertex vert
#pragma fragment frag
sampler2d _maintex;
float4 _maintex_st;
float _rimfactor;
float _distancefactor;
float4 _rimcolor;
float _distancefactor2;
float _distancefactor3;
struct a2v {
float4 vertex:position;
float2 uv:texcoord0;
float3 normal:normal;
};
struct v2f {
float2 uv:texcoord0;
float4 pos:sv_position;
float4 screenpos:texcoord1;
float3 worldnormal:texcoord2;
float3 worldviewdir:texcoord3;
};
v2f vert (a2v v) {
v2f o;
o.pos=unityobjecttoclippos (v.vertex);
//computescreenpos function to get the viewport coordinates xy before normalization
//z component is the z value of the clipping space, range [-near, far]
o.screenpos=computescreenpos (o.pos);
o.uv=transform_tex (v.uv, _maintex);
//compute_eyedepth function, convert the z component range [-near, far] to [near, far]
compute_eyedepth (o.screenpos.z);
o.worldnormal=unityobjecttoworldnormal (v.normal);
o.worldviewdir=worldspaceviewdir (v.vertex) .xyz;
return o;
}
float4 frag (v2f i):sv_target {
float3 maintex=1-tex2d (_maintex, i.uv) .xyz;
//Get depth texture,Convert the sampled depth texture value to the corresponding depth range through lineareyedepth function
float scenez=lineareyedepth (sample_depth_texture_proj (_cameradepthtexture, unity_proj_coord (i.screenpos)));
//observe the difference in spatial depth,The smaller the value, the greater the color value
float distance=1-saturate (scenez-i.screenpos.z);
//Eliminate the aliasing generated when the internal depth changes greatly
if (distance>0.999999)
{
distance=0;
}
//Adjust the change curve of depth difference
distance=pow (saturate (_distancefactor * log (distance) + _distancefactor3), _distancefactor2);
//The greater the angle, the brighter the edge light
float rim=1-abs (dot (normalize (i.worldnormal), normalize (i.worldviewdir)));
rim=pow (rim, _rimfactor);
float4 col=float4 (0,0,0,0);
col=lerp (col, float4 (_rimcolor.rgb, 0.3), maintex.r);
//Gradient according to edge light and depth difference
col=float4 (_rimcolor.rgb, lerp (col.a, _rimcolor.a, distance));
col=lerp (col, _rimcolor, rim);
return col;
}
endcg
}
}
}
``````

### Related articles

• Previous JavaScript prohibits right-click to save the picture, prohibits the realization code of dragging and dropping pictures
• Next JavaScript implementation code that prohibits users from saving pictures