深度测试:
ZTest [_ZComp] shader属性Enum(
/ LEqual / Always / Never(Off) / Greater / Less /GEqual / Equal / NotEqual
相机位置1 :绘制顺序:绿红蓝
相机位置2:绘制顺序:绿蓝红
红:LEqual 绿:LEqual 蓝:Greater
渲染队列都是2000
Shader "may/Depth test"
{
Properties
{
[Header(Depth)]
[Enum( Off,0,On,1)]_ZWriteMode("Z Write Mode", Float ) = 1
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTestMode("Z Test Mode", Float) = 4
[Header(Diffuse)]
_BaseColor ("Base Color", 2D) = "white" {}
_ColorTint ("Color Tint", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags { "Queue" = "Geometry" "RenderType"="Opaque" }
LOD 100
Pass
{
Name "Z Test"
Tags {"LightMode" = "ForwardBase"}
ZWrite [_ZWriteMode]
ZTest [_ZTestMode]
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
struct a2v
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _BaseColor;
float4 _BaseColor_ST;
fixed4 _ColorTint;
v2f vert (a2v v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _BaseColor);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// diffuse
fixed4 diffuseColor = tex2D(_BaseColor, i.uv) * _ColorTint;
return diffuseColor;
}
ENDCG
}
}
}
XRay:
正常效果
Shader "may/XRay Depth Test"
{
Properties
{
_AmbientOcclusion("AO Map", 2D) = "white"{}
_BaseColor ("Base Color", 2D) = "white" {}
_ColorTint("Color Tint", Color) = (1,1,1,1)
_XRayColor("XRay Color", Color) = (1,1,1,1)
_SpecularPow("Specular Pow", Range(1, 40)) = 8
}
SubShader
{
CGINCLUDE
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
sampler2D _AmbientOcclusion;
float4 _AmbientOcclusion_ST;
sampler2D _BaseColor;
float4 _BaseColor_ST;
fixed4 _ColorTint;
fixed4 _XRayColor;
half _SpecularPow;
struct a2v
{
float4 vertex :POSITION;
fixed3 normalMS :NORMAL;
float2 uv :TEXCOORD;
};
struct v2f
{
float4 pos :SV_POSITION;
fixed3 posWS :TEXCOORD;
float4 uv :TEXCOORD1;
half3 normalWS :TEXCOORD2;
SHADOW_COORDS(3)
};
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.posWS = mul(unity_ObjectToWorld, v.vertex);
o.uv.xy = TRANSFORM_TEX(v.uv, _AmbientOcclusion);
o.uv.zw = TRANSFORM_TEX(v.uv, _BaseColor);
o.normalWS = UnityObjectToWorldNormal(v.normalMS);
TRANSFER_SHADOW(o)
return o;
}
fixed4 fragRegularBase(v2f i):SV_TARGET0
{
fixed3 normalWS = normalize(i.normalWS);
fixed3 viewDirWS = normalize(UnityWorldSpaceViewDir(i.posWS));
fixed3 lightDirWS = normalize(UnityWorldSpaceLightDir(i.posWS));
//ambient
fixed3 ambientColor = UNITY_LIGHTMODEL_AMBIENT.rgb * tex2D(_AmbientOcclusion, i.uv.xy);
//diffuse
fixed3 albedo = _ColorTint * pow( tex2D(_BaseColor,i.uv.zw), 2.2); // Gamma correct
fixed Lambert = max(0, dot(lightDirWS, normalWS));
fixed3 diffuseColor = albedo * _LightColor0.rgb * Lambert;
//specular
fixed3 halfVector = normalize(viewDirWS + lightDirWS);
fixed3 specularColor = _LightColor0 * pow( max(0, dot(halfVector, normalWS)), _SpecularPow );
//shadow
//fixed atten = SHADOW_ATTENUATION(i);
UNITY_LIGHT_ATTENUATION(atten, i , i.posWS);
fixed4 finalColor = fixed4(ambientColor + (diffuseColor + specularColor) * atten, 1);
return pow(finalColor, 0.45); // convert to Gamma4
}
fixed4 fragRegularAdd(v2f i):SV_TARGET0
{
fixed3 normalWS = normalize(i.normalWS);
fixed3 viewDirWS = normalize(UnityWorldSpaceViewDir(i.posWS));
fixed3 lightDirWS = normalize(UnityWorldSpaceLightDir(i.posWS));
//diffuse
fixed3 albedo = _ColorTint * pow( tex2D(_BaseColor,i.uv.zw), 2.2); // Gamma correct
fixed Lambert = max(0, dot(lightDirWS, normalWS));
fixed3 diffuseColor = albedo * _LightColor0.rgb * Lambert;
//specular
fixed3 halfVector = normalize(viewDirWS + lightDirWS);
fixed3 specularColor = _LightColor0 * pow( max(0, dot(halfVector, normalWS)), _SpecularPow );
//shadow
UNITY_LIGHT_ATTENUATION(atten, i , i.posWS);
fixed4 finalColor = fixed4( (diffuseColor + specularColor) * atten, 1);
return pow(finalColor, 0.45); // convert to Gamma4
}
fixed4 fragXRay(v2f i):SV_TARGET0
{
return fixed4(1,1,0.5,1);
}
ENDCG
Tags { "Queue" = " Geometry" "RenderType"="Opaque" }
LOD 100
pass
{
Name "XRay"
Tags{"LightMode" = "ForwardBase"}
ZTest Greater
ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment fragXRay
ENDCG
}
Pass
{
Name "RegularBase"
Tags{"LightMode" = "ForwardBase"}
ZTest LEqual
CGPROGRAM
#pragma vertex vert
#pragma fragment fragRegularBase
#pragma multi_compile_fwdbase
ENDCG
}
Pass
{
Name "RegularAdd"
Tags{"LightMode" = "ForwardAdd"}
ZTest LEqual
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment fragRegularAdd
#pragma multi_compile_fwdadd
ENDCG
}
}
FallBack "Diffuse"
}
主要是两个Pass P1:一个是画露出的部分 vert fragRegularBase fragRegularAdd
P2:一个是画遮挡的部分 vert fragXRay
要先画P2, 如果先画P1,P1要写入深度,再画 P2 会画到自遮挡的部分
先画 P1 不能写入深度,模型深度(较大)不然会覆盖掉墙(较小)的深度
保证墙在该模型前面绘制,即墙先写入深度。
其实可以在Transparent队列渲染,保证渲染顺序
较大深度值覆盖较小的深度值:
ZWrite On ZTest Greater
物体:墙,熊,绿块,蓝块,
渲染队列都是 2000,渲染顺序:墙,蓝块,绿块,熊被遮挡部分,熊露出的部分fwdbase,熊露出部分fwdadd。
渲染蓝块时,会将墙写入的较小的深度,改为较大的深度,此时绿块和熊的部分算作没被墙遮挡。