I was trying to achieve something similar to how shadow catchers work in Blender. I found this shader online https://github.com/ZhuoyueLyu/Unity_Shadow_Receiver which does seem to somewhat replicate shadow catchers but lacks the "holdout" feature shadow catchers have in Blender. Essentially being transparent, catching shadows but also blocking objects behind it. I haven't edited .shader files before so don't know where to even start. If there's an alternative shader or way to do it that would be great as well. Attached an example from Blender - expected outcome and the above shader in Unity (other objects such as the floor are still rendered behind the objects instead of leaving it empty to fill with solid color or skybox or whatever).
#Shadow catcher doesn't block objects behind it
1 messages · Page 1 of 1 (latest)
Leaving it "empty" to fill with "whatever" seems to be doing a lot of heavy lifting here
In Blender the Holdout shader is treated as alpha transparency on the rendered image
May not be so simple in Unity because you're not typically rendering an image that has an alpha channel
If you know that you'll only need to render a color, or the skybox or something similarly predictable, you could render it in the object's shader and multiply received shadow on it
The skybox texture is simple to sample with 3D coordinates so you can have a "window" into the sky anywhere
Does it not have an alpha channel even if I use a Render Texture with an RGBA format? I just imagined that a regular shader was rendering a pixel from a background object then rendering the middle cube's pixel and replacing old value (which would then need to be forced as a 0,0,0,0 pixel) which then can be replaced if any object is in front of it and gets rendered later. I'll admit I don't entirely know how shaders work in Unity but it didn't seem like something crazy in theory.
Mostly sounds like you're describing what's already happening
The cube is rendered after the background, and it has alpha 0 so the background shows through
But in that case the background is simply the floor
There isn't conceptually anything "behind" the rendered image to show, at that point anyway
Read that a few times but don't really understand what you are proposing to do instead. In the end result I will need a Render Texture that has everything black but the pixels where a specific object is visible directly or its shadow (or ideally even reflection or other indirect rays but I understand that might be too hard) being white. Essentially a more complex "isvisible" check.
I guess so. Maybe if the object cast a white shadow and everything else is just pure black no shadow catcher would be needed.
Proposing instead that the shader that calculates the color of the object would work out the "background" using shader calculations and render that as the color instead
If that can be calculated in the shader, there's no need for multiple render textures
If you need just a sky for example, that'd be pretty easy
If you need arbitrary objects to show through, that method becomes very difficult
With render textues / stacked cameras there is probably a way to make it work with alpha processing
With that method you'd render first an image of what the "behind" background is, then everything that's in front of it and in some way cut out / exclude from rendering the pixels that only have your holdout material
Though I'm really unclear on what exact steps that needs
An easier variation of that method is that instead of trying to make the second rendered texture transparent in specific parts is to just use the first "behind" texture in the holdout fragment shader, the same way you'd draw the color or the sky in the first method