Correct shadows for cutout shader with (dithered) transparency

Hi,

I’m working on a cutout shader that takes in an array of positions and only shows pixels close enough to those positions. This works well as an opaque shader and with the addshadow keyword the shadow behaves as expected.

However, on top of clipping the pixels outside of the range of the given positions, I also need the shader to be transparent. I tried doing this with an alpha blended shaders, but there the shadows were incorrect, either not following the cutout (so in the case of a plane showing the full shadow of the plane instead of just the visible part) / being blocked by the pixels that were clipped / both.

I’ve had the most success with the following setup:

And then editing the generated code so that the shadow pass only uses the cutout value for clipping, and not the dither value (so the surface function uses clip(distanceValue) rather than clip(min(distanceValue, ditherValue))). This works well to cast a solid shadow, but it can’t receive shadows and the shadows don’t match up with the opacity of the object.

Ideally it should also be able to receive shadows, and cast a shadow with the same dither pattern as the object itself. However if I leave the shadow pass as it’s originally generated (dithering included), then the shadow doesn’t dither but instead completely disappears once the alpha drops below around 65%.

Can this be fixed so that the shadows work as I would like? And why does the dithering not work in the shadow pass? I’ve included the original shader (revealshader.shader) and the edited shader after the original is generated by Unity (revealshader_edited.shader).

6070908–658236–revealshader.shader (2.93 KB)
6070908–658245–revealshader_edited.shader (72.9 KB)

There’s a long time bug with Surface Shaders that the screenPos isn’t set in the generated shadow caster pass. The only solution at the moment is to either use a custom screenPos (not named screenPos) or to not use addshadow and include a custom hand written shadow caster pass in the shader. You can copy/paste the shadow caster pass from the modified shader directly into the original surface shader.