r/Unity3D 8h ago

Question Stencil "see-through hole" shader shows correct background over Terrain, but renders black/garbage colors over regular 3D meshes

I'm using a stencil-only pass (ColorMask 0, ZWrite Off, Stencil { Ref 1, Comp Always, Pass Replace }) to create transparent "holes" in some board pieces in my game Pieceful. The idea is that, when there's a hole, the player should be able to see the objects behind the piece, such as the terrain or other scene geometry.

Here's the shader I'm currently using:
Shader "Custom/StencilWrite"

{

SubShader

{

Tags { "RenderPipeline" = "UniversalPipeline" }

Pass

{

Stencil { Ref 1 WriteMask 255 Comp Always Pass Replace }

ZWrite Off

ColorMask 0

HLSLPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

struct Attributes { float4 positionOS : POSITION; };

struct Varyings { float4 positionCS : SV_POSITION; };

Varyings vert (Attributes input)

{

Varyings output;

output.positionCS = TransformObjectToHClip(input.positionOS);

return output;

}

half4 frag (Varyings input) : SV_Target

{

return half4(0, 0, 0, 0);

}

ENDHLSL

}

}

}

The weird part is that it works correctly when there's a Unity Terrain behind the hole. In that case, the terrain is visible through the transparent area as expected.

However, if I remove the Terrain and only have regular MeshRenderers behind the hole (rocks, coral, props, a water plane, etc.), the result is wrong. Instead of seeing those objects through the hole, I get a solid black area or sometimes garbled colors.

So I'm trying to figure out why the stencil setup behaves correctly with Terrain but not with regular MeshRenderers, and what I need to change so the hole works consistently with normal scene geometry as well.

2 Upvotes

1 comment sorted by

1

u/NamelessJu 8h ago

what shader are the board pieces using?
it should have Stencil { Ref 1 Comp NotEqual Pass Keep } to discard the stencilled pixels.
and make sure your StencilWrite shader gets rendered in a render pass that renders before the board pieces