当前位置: 移动技术网 > IT编程>开发语言>c# > Unity Shader相交算法实现简易防能量盾

Unity Shader相交算法实现简易防能量盾

2020年06月23日  | 移动技术网IT编程  | 我要评论
unity shader学习:相交算法实现简易防能量盾主要思路:对比物体和场景深度图在观察空间下的深度差值,深度差越小表示相交,颜色越深,在加上边缘光勾出轮廓。shader部分:shader "unl

unity shader学习:相交算法实现简易防能量盾

主要思路:对比物体和场景深度图在观察空间下的深度差值,深度差越小表示相交,颜色越深,在加上边缘光勾出轮廓。

shader部分:

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函数,得到归一化前的视口坐标xy
 //z分量为裁剪空间的z值,范围[-near,far]
 o.screenpos = computescreenpos(o.pos);
 o.uv = transform_tex(v.uv,_maintex);
 //compute_eyedepth函数,将z分量范围[-near,far]转换为[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;
 //获取深度纹理,通过lineareyedepth函数将采样的深度纹理值转换为对应的深度范围[near~far]
 float scenez = lineareyedepth(sample_depth_texture_proj(_cameradepthtexture,unity_proj_coord(i.screenpos)));
 //观察空间深度差,值越小颜色值越大
 float distance =1 - saturate(scenez - i.screenpos.z);
 //消除内部深度变化较大时产生的锯齿
 if (distance>0.999999)
 {
 distance = 0;
 }
 //调整深度差值的变化曲线
 distance = pow(saturate(_distancefactor * log(distance) + _distancefactor3), _distancefactor2);

 //角度越大边缘光越亮
 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);
 //根据边缘光以及深度差渐变
 col = float4(_rimcolor.rgb,lerp(col.a,_rimcolor.a, distance));
 col = lerp(col, _rimcolor, rim);
 return col;
 }

 endcg
 }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网