Home>
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 part:
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
}
subshader {
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;
sampler2d _cameradepthtexture;
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
Related questions
- Unity Shader achieves cutting effect
- Unity Shader realizes the fog of 2D games
- Unity Shader realizes the sketch effect
- Unity Shader implements sketch-style rendering
- Unity Shader achieves graphics drawing (blue sky, white clouds and sea)
- Unity shader realizes the effect of vertex animation wave
- Unity shader to achieve glass refraction effect
- Unity Shader achieves dynamic fog effect
- Unity Shader achieves glass material effect