2D renderer Depth of Field effect.

Hi everyone! I want to add some DOF effect just like Hollow Knight and Ori. Actually I was searching on this topic few days and still can't figure it out how to do it with Shader.

What I already known is, sprite is all transparent so it doesn't open ZWrite by default. So I write a simple sprite shader with ZWrite on, and I can tell it has depth test working, but still not correct DOF effect. Why?
However, I found something new in the 2D renderer data setting.
[quote]
Use Depth/Stencil Buffer
This option is enabled by default. Clear this option to disable the Depth/Stencil Buffer. Doing so might improve your project’s performance, especially on mobile platforms. You should clear this option if you are not using any features that require the Depth/Stencil Buffer (such as Sprite Mask).
[/quote]
So we already have depth buffer right? However, I can neither find depth texture nor the CameraSortingLayerTexture in the frame buffer. And the _CameraDepthTexture return nothing at all. Is there any info I missed?

Hope someone can shed some light on me, thanks!

8404872--1110024--2dRendererData_properties.png

1 Like

I have the same question as you. Hope there is a solution.

3 Likes

Same here, anyone from unity can help with this?

@rustum Maybe you can shad some light on this issue?

I straight up gave up on this.
After weeks of digging what I found is that the 2D renderer is, sorry, horrible. If you really need DoF, you should use the good old Built In Renderer, where you will be able to found a good number of blur shaders, because on this renderer it was actually possible to write some !

(You can look all you want, you won't find a single blur shader for the 2D renderer, at least, it was straight up impossible 2 months ago)

Or of course you can take the road I'm taking : baking blur in all your sprites with different blur sizes, it's FAR from ideal, but at least you know what you will end up with...

Good luck !

[quote=“RemDust”, post:4, topic: 892872]
I straight up gave up on this.
After weeks of digging what I found is that the 2D renderer is, sorry, horrible. If you really need DoF, you should use the good old Built In Renderer, where you will be able to found a good number of blur shaders, because on this renderer it was actually possible to write some !

(You can look all you want, you won’t find a single blur shader for the 2D renderer, at least, it was straight up impossible 2 months ago)

Or of course you can take the road I’m taking : baking blur in all your sprites with different blur sizes, it’s FAR from ideal, but at least you know what you will end up with…

Good luck !
[/quote]

It’s actually pretty easy to do.

You just need to add a URP/HDRP lit shader onto a sprite and make sure the shader surface options are set to Opaque with Alpha Clipping on. I’ve been using it on my game which has DoF.

9739663--1393219--Screenshot 2024-02-22 at 3.15.17 PM.jpg

Hey @VinHill !
Would you mind elaborate a bit ?
Also sharing more screenshots of your setup in the scene and relevant editor/hierarchy ?

I’m not sure I understand your setup here.

Thanks a lot =)

I have some questions about this myself. Obviously you can use the URP 3D renderer to get depth. Obviously this will require a opaque shader with cutout for any transparency. The 2D shaders don't write to the depth buffer by default for good reason. I'm a pretty visual person so here's a visual aid:

The ladder sprites and spheres are using a slightly modified lit Shadergraph shader from the URP 3D renderer, whereas the tilemap and character sprite are using the 2D shader. Those don't write to the depth buffer, so they don't appear in the depth texture. Understandable so far. Here's where it starts making less sense.

If I do nothing but swap to the 2D Renderer, which does have Depth Texture and Depth Buffer enabled, the _CameraDepthTexture is no longer written to and the CopyDepth event in the render pipeline never occurs. That's odd, it seems like that should be specifically what that option is for, no?

But maybe the buffer is hidden somewhere I'm not finding it. This still doesn't give us a good user experience, because the 2D Lit Shadergraph doesn't give us good options for support anyway. So you're compiling the Shadergraph to code and messing with pretty mid to high level stuff by default.

There are good reasons for wanting this functionality in the 2D Renderer. We have 2DLights. We have performance optimizations. And hey, depth of field can look great. Play Sheepy free on Steam, the DoF there is incredibly atmospheric. There should be options inside Shadergraph to set a URP lit or unlit sprite to opaque cutout and have it write to the depth buffer. The one that it ostensibly supports.

If you're willing to deal with 1bit alphas for the affected sprites, there's no reason the depth of field post process effect (along with other cool depth stuff) can't just work without modifying shader and renderer code.

Am I missing something?

That looks pretty, pretty good! But I don’t quite understand how you did it. Could you maybe tell a bit more?