当前位置:网站首页>【Unity Shader】插入Pass实现模型遮挡X光透视效果

【Unity Shader】插入Pass实现模型遮挡X光透视效果

2022-07-07 16:31:00 InfoQ

原有shader不变,额外插入一个pass通道用于渲染遮挡部分,实现X光透视效果正常渲染Pass,只渲染未遮挡部分;X光透视Pass,只渲染被遮挡部分。

可用于处理玩家被障碍物遮挡时候的描边显示,或者透视敌人等特殊显示效果。

实现效果:



分Pass渲染:

  • 透视效果Pass,在渲染的时候使用ZTest Greater,首先渲染的是前面遮挡的Cube,此时深度缓存中有了Cube的深度值。然后再渲染模型,模型未遮挡的部分深度测试不通过,不会渲染,被遮挡的部分深度测试通过,正常显示。
  • 正常渲染Pass,首先渲染的是前面遮挡的Cube,此时深度缓存中有了Cube的深度值。然后再渲染模型,模型被遮挡的部分深度测试失败,不会渲染,未被遮挡的部分正常显示。

深度测试ZTest可设置的测试规则:
  • ZTest Less:深度小于当前缓存则通过
  • ZTest Greater:深度大于当前缓存则通过
  • ZTest LEqual:深度小于等于当前缓存则通过
  • ZTest GEqual:深度大于等于当前缓存则通过
  • ZTest Equal:深度等于当前缓存则通过
  • ZTest NotEqual:深度不等于当前缓存则通过
  • ZTest Always:不论如何都通过

Shader代码:

//原Pass不变,插入一个Pass,用于显示模型遮挡部分
 
Shader "Test/Model_XRay"
{
Properties
{
_MainTex ("Diffuse (RGB)", 2D) = "grey" {}
_Color("Color (RGBA)", Color) = (1,1,1,1)
 
_XRayColor("XRay Color", Color) = (1,1,1,1)
}

SubShader
{
Tags
 {
 "RenderType"="Opaque"
 "Queue"="AlphaTest+1"
 "IgnoreProjector"="True"
 }
 
LOD 200
Fog { Mode Off }
 
//渲染X光透视效果的Pass
Pass
{
Blend SrcAlpha One
ZWrite Off
ZTest Greater
 
CGPROGRAM
 
#pragma vertex vert
#pragma fragment frag
 
#include "Lighting.cginc"
 
fixed4 _XRayColor;
 
struct v2f
{
float4 pos : SV_POSITION;
float3 normal : normal;
float3 viewDir : TEXCOORD0;
};
 
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.viewDir = ObjSpaceViewDir(v.vertex); //计算顶点到相机的向量
o.normal = v.normal;
return o;
}
 
fixed4 frag(v2f i) : SV_Target
{
//利用法线跟视线向量的点乘值计算颜色浓度
float3 normal = normalize(i.normal);
float3 viewDir = normalize(i.viewDir);
float rim = 1 - dot(normal, viewDir);
return _XRayColor * rim;
}
 
ENDCG
}
 
Pass
{
 CGPROGRAM
 
 //定义顶点/片元着色器代码
 #pragma vertex vert
 #pragma fragment frag
 
 #include "UnityCG.cginc"
 
 sampler2D _MainTex; 
 
 //定义顶点着色器的输入
 struct a2v
 {
 float4 vertex : POSITION;
 float2 uv :TEXCOORD0;
 };
 //定义顶点着色器的输出、片元着色器的输入
 struct v2f
 {
 float4 vertex : SV_POSITION;
 float2 uv:TEXCOORD0;
 };
 
 v2f vert (a2v v)
 {
 v2f o;
 o.vertex = UnityObjectToClipPos(v.vertex);
 o.uv = v.uv;
 return o;
 } 
 fixed4 frag (v2f i) : SV_Target
 {
 return tex2D(_MainTex,i.uv);
 }
 ENDCG
 
}
 
}
FallBack "Diffuse"
}

原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/e1f142aef14de3d391686dc16