Search Unity

Question URP Deferred depth texture unavailable

Discussion in 'Shaders' started by bb-greg, Feb 27, 2023.

  1. bb-greg

    bb-greg

    Joined:
    Aug 31, 2022
    Posts:
    4
    I'm experimenting with sobel edge detection with depth textures to make toon shader outlines, mainly within the confines of shader graph in URP. This all worked perfectly up until switching to deferred rendering and now the outline rendering has broken completely. Tracking this down, I found that the shader graph node "Scene Depth" no longer gave the correct result. Blitting "Scene Depth" argb to the screen ("after rendering opaques" pass event), I found that the correct depth information would appear in forward rendering, but the screen would be devoid of data when in deferred. It does work if I choose any render pass event after rendering opaques, but the toon shader is material based rather than a full screen effect and I need the desired result as the world is being rendered and ideally on the same frame.

    upload_2023-2-27_18-1-52.png
    ShaderGraph input with the 2 results on the right (forward / deferred)

    To circumnavigate this, I tried using a camera to output depth to a render texture but found I had the exact same issue. Fine in forward, broken in deferred.

    I'm aware of the 4 g-buffers referenced in the documentation on deferred lighting: https://docs.unity3d.com/Manual/RenderTech-DeferredShading.html

    I thought I would try to use the g buffer depth texture created there. However, any time I have tried to sample any of the gbuffer textures listed (CameraGBufferTexture#) and they always return grey. I see lots of articles and forum posts suggesting their usage, but I think all of them are dated prior to URP.

    Are these textures now deprecated in some way? If so, how can I either obtain the depth buffer information or how would I create a depth texture that works during deferred?
     
    Last edited: Feb 28, 2023
  2. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    Hi, the reason that you can access scene depth during opaque rendering in Forward is because of depth (normals) pre-pass. You can find it in Frame Debugger.

    The current URP won't execute depth pre-pass for deferred objects because (default) URP doesn't need it.

    If you need to access scene depth in a gbuffer pass (in your shader graph using deferred), you can either create a deferred depth pre-pass renderer feature or force the shader to be in forward (cannot be done in shader graph).

    By the way, what makes you'd like to switch to deferred?
     
  3. bb-greg

    bb-greg

    Joined:
    Aug 31, 2022
    Posts:
    4
    Thanks for the response!

    The project switched to deferred because there's a greater emphasis on multiple light sources in the scene than initially expected, especially with the environments, which may be rendered in a more realistic manner than the characters in the scene. If the characters could be rendered in forward, that would probably be fine, but alas, the toon renderer is all shader graph atm (starting to think I should port it to shader language tbh).

    I actually have a render feature that creates a depth normal texture and that still works since changing to deferred, and when fed through the sobel edge detection provides great outlines for details, but it doesn't work too great for general outlines. I currently haven't been able to get the depth from this texture like I have been able to with Scene Depth unfortunately... maybe I need to investigate that further.

    The idea of having a pre-pass renderer feature seems the way to go. Should I be able to reference the "CameraGBufferTexture" textures if I operate this "Before rendering GBuffer" or "After rendering GBuffer"? Or should I abandon accessing the gbuffers and create my own depth texture via other means?
     
  4. wwWwwwW1

    wwWwwwW1

    Joined:
    Oct 31, 2021
    Posts:
    769
    It's difficult to have custom lighting models (Toon) in deferred rendering path because the actual lighting is not done by your shader graph but URP's deferred lighting shader (supports Lit & Simple Lit lighting models only).

    If your project is on 2022.2 or higher, you can switch the rendering path to "Forward+" (Forward with better light culling) which has no per object lights limitation.

    Is the Toon shader simply combines URP's Lit shading + outline?

    If no (it's cell shading), I suggest using "Forward+" because you cannot access all deferred lights in GBuffer pass (shader graph). In other words, currently maximum 8 lights per object when accessing lights in GBuffer pass.

    You can only access "CameraGBufferTexture" after rendering GBuffer, or you'll get GBuffer from previous frame. But the biggest issue is that the shader graph is rendering to GBuffer, which means you cannot access it at the same time.