- Home /
How to make clip() work with Ambient Occlusion?
Hey so I've made a shader that dithers the geometry behind the player so they're always possible to be seen! But I think even the clipped geometry is writing in the depth buffer, causing a bug on this Ambient Occlusion effect. Is there any fix to this? Am I thinking this in the wrong way?
Here's an image with the buggy outcome:
Here's the shader code:
SubShader
{
Tags { "RenderType"="Opaque" "Queue" = "Geometry-2" }
//Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
LOD 200
//Blend SrcAlpha OneMinusSrcAlpha
Cull Back
ZWrite On
ZTest LEqual
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 ground = tex2D (_GroundTex, IN.worldPos.xz) * _Color;
fixed4 wallA = tex2D (_WallTex, IN.worldPos.xy) * _Color;
fixed4 wallB = tex2D (_WallTex, IN.worldPos.zy) * _Color;
fixed4 c = ground * abs(IN.worldNormal.y) + wallA * abs(IN.worldNormal.z) + wallB * abs(IN.worldNormal.x);
o.Albedo = c.rgb;
//float ditherValue = GetDitherValue(IN.screenPos.xy / IN.screenPos.w, _DitheringTex, _DitheringTex_TexelSize);
float ditherValue = GetDitherValue(IN.screenPos.xy / IN.screenPos.w, _DitheringTex, _DitheringTex_TexelSize);
ClipParts(IN, ditherValue);
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
LOD 200
//Blend SrcAlpha OneMinusSrcAlpha
Cull Front
ZWrite On
ZTest LEqual
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
void surf (Input IN, inout SurfaceOutputStandard o)
{
//float ditherValue = GetDitherValue(IN.screenPos.xy / IN.screenPos.w, _DitheringTex, _DitheringTex_TexelSize);
float ditherValue = GetDitherValue(IN.screenPos.xy / IN.screenPos.w, _DitheringTex, _DitheringTex_TexelSize);
o.Albedo = fixed3(0.,0.,0.);
ClipParts(IN, ditherValue);
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = 1.;
}
ENDCG
}
I've removed some functions I call for the sake of making the question smaller.
Tell me if you need more info.
Answer by Namey5 · Mar 21, 2021 at 02:57 AM
The depth texture is tied into the shadowcaster pass of a shader - in this case you are updating the visibility of the main shader without affecting the shadowcaster pass, so the depth texture will think the whole object is still being rendered. With surface shaders this is a fairly simple fix - just add the 'addshadow' parameter to the surface declaration;
#pragma surface surf Standard fullforwardshadows addshadow
From what I can see this shader can also be done in a single pass rather than two;
struct Input
{
...
float3 viewDir;
...
};
...
Cull Off
CGPROGRAM
#pragma surface surf Standard fullforwardshadows addshadow
#pragma target 3.0
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 ground = tex2D (_GroundTex, IN.worldPos.xz) * _Color;
fixed4 wallA = tex2D (_WallTex, IN.worldPos.xy) * _Color;
fixed4 wallB = tex2D (_WallTex, IN.worldPos.zy) * _Color;
fixed4 c = ground * abs(IN.worldNormal.y) + wallA * abs(IN.worldNormal.z) + wallB * abs(IN.worldNormal.x);
o.Albedo = c.rgb * (dot (IN.viewDir, IN.worldNormal) < 0);
float ditherValue = GetDitherValue(IN.screenPos.xy / IN.screenPos.w, _DitheringTex, _DitheringTex_TexelSize);
ClipParts(IN, ditherValue);
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
The basic idea is to check if we are drawing a backface and just manipulate the parts that need to change on each side of the mesh (dot (viewDir, worldNormal) will be positive if we are drawing a backface).
Your answer
Follow this Question
Related Questions
Use camera depth texture to find distance from camera 0 Answers
UI masking in a jet fighter HUD 0 Answers
Gradient mapping in shader graph 1 Answer
Intersection Highlight Shader -1 Answers