SpiralCircus

I'm making use of the "Spine/Sprites/xxx" shader to allow for depth of field post-processing effects to work on my animated sprites.

I was wondering if you had a some info somewhere about how the "write to depth" is acheived such that it writes to the camera depth texture, while still showing the nice transparent smooth alpha sprite. Is it using replaement shaders to replace the in-built unity cameraDepthTexture shader?

Is it possible to leverage this in my own custom sprite shaders for use on regular sprites that aren't making use of SkeletonRenderer? I'd love some advice about this, since you've already solved a problem I've been struggling with for months, namely, how to render smooth transparent sprites while writing a rougher cutout to the camera depth texture.

TL/DR: How do i utilise the CameraDepthTexture replacement shader from Spine in my own custom shaders?
SpiralCircus
Posts: 9

Harald

Have you tried creating a copy of the CameraDepthTexture shader and adding your required parts to it? Then you would need to call camera.RenderWithShader() with your respective shader.

At the end you could copy and adapt the part
SubShader {
Tags { "RenderType"="Sprite" }
to add your own custom type like
SubShader {
Tags { "RenderType"="MyCustomSprite" }
Be sure to have the corresponding line clip( alpha - _Cutoff ); in the fragment shader as well to get the cutout effect at the depth buffer. Also be sure to name the parameters like they are in your original shader.
User avatar
Harald

Harri
Posts: 147

SpiralCircus

Thanks for the info. I noticed that when I use one of the spine "Sprites/XXX" shaders, I can toggle on depth write and it writes to depth, without having to call
camera.RenderWithShader()
anywhere. This is the case even when i use the material on a simple sprite renderer with no spine components attached. Am I missing something? How is this acheived without the camera code in place?

Another thing I noticed when testing the above is that when depth write is toggled on, the sprite starts to look jagged again, following the depth alpha cutoff value, is this expected behaviour? To me it looks the same as simply changing the render type to "cutout" using the standard shader, but I thought the purpose of this replacement was to visually render the soft edges as with a transparent shader, but also to render the cutout sprite to the depth texture for screen-space post processing.

My apologies if these questions are a little uninformed, i'm very much not a graphics programmer. I'm fine with the csharp side of things but I'm not so great with shaders.
SpiralCircus
Posts: 9

Harald

Have you tried enabling Write to Depth and setting Depth Alpha Cutoff to 0.0001? This results in nice blended results with no jagged borders (because the cutoff is set to "only discard when alpha <= 0.0001") while still rendering the whole sprite to the depth buffer:

WriteToDepthSettings.PNG

WriteToDepthHero.PNG
Magnified view of the Hero character. Enabled depth write provides the correct depth value for the camera blur effect.

---

[Edit:]
Note however that when you use a blur effect and have multiple sprites layered behind each other, then by design you will have problems in non-cut-off areaswhen setting the cutoff threshold to 0.0001 - then a nicely alpha-blended 95% transparent black pixel will receive 95% of the background color, and thus the background pixel will be perfectly sharp (non-blurred) when the character is in focus, where it should be blurry instead.

WriteToDepthHeroBlur.PNG
Some background pixels around the border wrote to character's depth since they were not discarded at 5% opacity - hence they are not blurry but as sharp as the character.

In this case you cannot handle this in a single render pass - that's where you need the two different alpha cutoff thresholds:
1) one that is low enough to not discard the transparent pixel in the first pass, and then
2) another one at e.g. 0.5 that blurs everything that is mostly transparent and therefore shall count as background.
This case is where the camera.RenderWithShader() replacement shaders come in handy, since they can render another pass just to write different depth values.
You do not have the required permissions to view the files attached to this post.
User avatar
Harald

Harri
Posts: 147

SpiralCircus

Thanksyou for the detailed reply Harald. I'm the lone programmer on our team so I frequenctly have to bounce between areas of focus for particular deadlines, which means sometimes I can't quickly go back and test your advice, but I'll let you know how I get on when i get back to that problem. Really appreciate you taking the time to answer.
SpiralCircus
Posts: 9

Harald

You're welcome, hope it helps! No need to hurry at all.
User avatar
Harald

Harri
Posts: 147


Return to Unity