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: 11

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: 754

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: 11

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: 754

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: 11

Harald

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

Harri
  • Posts: 754

csumsky3

Hello! Glad I found this thread :) Wanting to do the same thing - get depth info for our spine objects so that we can use depth of field effects. However, when I try toggling on "Write to Depth" on a Spine/Sprite/Unlit shader, I get the following weirdness:

https://www.dropbox.com/s/hq4putsjdionnih/depth%20write%20issue.gif?dl=0

Is it because all of the skeleton's sprites are in the same z-space, so they're just all clipping? Maybe that's not the case, just a hunch! Happy to provide more details, but figured I'd just start there. Thanks!
csumsky3
  • Posts: 24

Harald

Hello! :)
You can set Z Spacing in the inspector of the SkeletonAnimation component, under the Advanced section.
User avatar
Harald

Harri
  • Posts: 754

csumsky3

:bigeyed: just like that huh! Thanks!
csumsky3
  • Posts: 24

Harald

You're welcome 8)
User avatar
Harald

Harri
  • Posts: 754

Bekko

hey , )

is it possible to add " Write to Depth" to the skeleton shader ?
Bekko
  • Posts: 27

Harald

It is possible, however the non-sprite shaders are kept simple on purpose - if we add too many things we end up at the Spine/Sprite/ shaders.
Is there a reason you don't want to use any of the Spine/Sprite/ shaders which provide this?
User avatar
Harald

Harri
  • Posts: 754

Bekko

hey @Harald

yes, the reason was, that my spine is rotating if the game object was > to an angle, but using the shader pixel vertex was strange,
skeleton shader worked perfectly but not good with the unity depth of field.. well

I was using

"transform.localEulerAngles = new Vector3(0, 180, 0);" to make a mirror,

but I thing I fix it using :

transform.localScale = new Vector3(-1, 1, 1);

sorry, thx
Bekko
  • Posts: 27

Harald

Bekko wrote:yes, the reason was, that my spine is rotating if the game object was > to an angle, but using the shader pixel vertex was strange
I fear I don't quite understand the above sentence.

Anyway, you could copy the existing Spine-SkeletonLit.shader shader file and modify the lines
// change this line to give it a new unique name: Shader "Spine/Skeleton Lit" {
// e.g. to this name:
Shader "Spine/Skeleton Lit Depth Write" {
and
either
  1. // change ZWrite Off to
    ZWrite On
    or
  2. // below [Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp("Stencil Compare", Float) = 0.0 // Disabled stencil test by default
    // add the line:
    _ZWrite ("Depth Write", Float) = 1.0

    // and change ZWrite Off to
    ZWrite [_ZWrite]

Then you can assign your new Spine/Skeleton Lit Depth Write shader as usual.
User avatar
Harald

Harri
  • Posts: 754

Bekko

thx
Bekko
  • Posts: 27


Return to Unity