Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Depth Priming Advantages?

Discussion in '2021.2 Beta' started by ImpossibleRobert, Jun 28, 2021.

  1. ImpossibleRobert

    ImpossibleRobert

    Joined:
    Oct 10, 2013
    Posts:
    517
    I saw the new beta includes Depth Priming in URP which sounds like an amazing feature for me. Was somebody already able to test it and the impact it makes? I have a scene with a lot of overlaying geometry (stencil based) and from what I understand Depth Priming can really cut down the render times because it will do a depth pass first and then only shade the pixels that are on top. That should do a massive boost especially for VR games I guess, or do I misunderstand something and the depth prepass is eating up all the gained render time already?
     
    JesOb likes this.
  2. mahdi_jeddi

    mahdi_jeddi

    Joined:
    Jul 18, 2016
    Posts:
    245
    We used to do force depth for different parts of the scene to optimize the rendering like this. We would even sort the triangles of some objects front to back (we had fixed camera angle). The win depends on a lot of things of course, but in the most dens areas of the scene we would get around 12% improvements. This should be even better, because it would apply to the whole scene and you wouldn't lose anything because of non-optimally sorted vertex buffers.
     
  3. NicoLeyman

    NicoLeyman

    Unity Technologies

    Joined:
    Jun 18, 2019
    Posts:
    33
    Hi,
    Depth Priming should improve mostly GPU timing in a lot of cases.
    The best results we've managed to observe were up to 16% less GPU time on Mac Metal.
    We observed 3% less CPU time and 7.5% less GPU time on Windows Vulkan.

    Actual gains are dependent on many factors:
    • Graphics API/Hardware/Platform: On desktop there are the variations between hardware and API's. On mobile there is variations of tile based hardware. This should in theory reduce the gains made by Depth Priming on tile based hardware when MSAA is enabled (to a point where performance could even be worse). However in practice we weren't able to observe this on the devices we tested.
    • Scene: is there lots of overlapping opaque geometry that can't be entirely handled by front to back sorting ?
      Depending on the scene we can skip a lot of redundant pixel shader invocations. With Depth Priming each opaque pixel should only be shaded once. Note that with Depth Priming enabled we try to skip the front-to-back sorting on the CPU so that should give a minor CPU frame time boost.
    • Opaque shader cost: The more expansive the shaders used in the scene, the more speedup you'll get from each pixel shader invocation that's being skipped.
    • Render setup: If your renderer setup doesn't already trigger the depth prepass, you will have to pay the cost of forcing this prepass so the Depth Priming optimization has the necessary information to optimise the opaque pass.
      This is the difference between Auto and Forced. Auto will only allow priming when there already is a prepass (like when SSAO is on) while Forced will make sure the prepass is performed to enable Depth Priming to take place.
    And lastly something to be aware of: Because text and UI rendering is injected into the opaque pass you'll want to do these in an overlay camera with the cameras Clear Depth setting disabled. Since we can't perform Depth Priming in that case the UI should come through while respecting the depth from the underlying camera.

    Other than the aforementioned UI/Text issue, there should be no visual differences in render results. If there are then please report them. There's one known artifacting issue on Mac with vertex displacement that we're aware of.
    When measuring performance please keep in mind that priming doesn't do anything on Auto if there's no depth prepass and Forced will then also include the cost of depth prepass. Since we have to respect the MSAA of the forward pass there will some increased memory usage from the depth prepass having to allocate its rendertarget as MSAA as well.

    Depth Priming has the potential to improve performance with some caveats (and hopefully the UI one can fixed in the future) but the feature has yet to be tested in the wild. I believe it was tested on VR as well so please feel free to give it a go.
     
    NotaNaN, hippocoder, Ruchir and 5 others like this.
  4. ImpossibleRobert

    ImpossibleRobert

    Joined:
    Oct 10, 2013
    Posts:
    517
    One question to concrete usage. Is it enough to simply activate it and the shaders automatically profit from it or do I need to adjust my own shaders explicitly? And are the default URP shaders taking advantage already?
     
  5. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    The build in URP shaders are already supported and unless you are handwriting your shaders from scratch there should be nothing special you should need to worry about. They just need a depth pass and ShaderGraph and most (if not all) the Asset store shader creation tools support or add this by default.

    Something to be aware of, just like any rendering technique the advantages are situational. Turning depth pre pass on could actually worsen performance depending one the scene,shaders,hardware,platform.ect.

    If you want more technical information about "Depth Priming" aka "Depth Pre-pass" you can google it, there is a lot informative and well written articles on it.
     
    ImpossibleRobert likes this.
  6. ImpossibleRobert

    ImpossibleRobert

    Joined:
    Oct 10, 2013
    Posts:
    517
    One more question: what is the difference between Depth Priming and today's Depth Texture in URP that I can toggle already?
     
  7. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    If you toggle on DepthTexture or if a ScriptableRendererPass request the depth texture then depth priming will automatically be used. The difference is now you have the option to force it, plus there is probably extra optimization from todays URP. I'm assuming that prior to the Depth Prime option that opaque objects might have still been sorted.
     
  8. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    @NicoLeyman i am porting some shaders from urp 11 to 12 right now and unfortunately depth priming breaks my toon + outline shader which draws both in the same shader but in different passes.
    so the outline just gets rejected because of depth testing.
    i wonder if it is needed to use ZTest Equal in all cases?
    needed for alpha testing to get rid of it but on a regular shader LEqual should do the job, right?
    other than that: maybe we could exclude some shaders from using another ZTest than the original from the material using shader tags?
     
  9. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    He mentions that Depth priming removes the need to sort opaque's, this might make it pretty difficult to get a toon outline shader using hull method to work properly because the depths could be written in random orders. I personally would make a custom ScriptableRenderer to render you're toon shaders, this would give you full control on how there rendered. You could removed the default universal shader tag from your shaders so they get skipped, then call your own Draw Renderers call from the scriptable context with your shader tag and specify the drawing order.
     
  10. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    oh, i did not see this. but actually he wrote:
    so they "try" - which i guess might be a bad idea as writing out the depth or depth normals would suffer from heavy overdraw then. less expensive than overdraw in the forward or gbuffer pass but still expensive.
     
  11. NicoLeyman

    NicoLeyman

    Unity Technologies

    Joined:
    Jun 18, 2019
    Posts:
    33
    This is correct. On the shader side we require a depth and depth normals pass. Depth written here should be the same as the depth of the opaque pass. So don't go optimising away vertex displacement in the depth pass.

    EDIT: Unlit ShaderGraph shaders should now also generate the required depth/depth normals shaders. Although I don't think you can alter the "unlit" normals from SG, they're just geometry based.

    Depth pre-pass is indeed the common name for this feature. I've opted to call it Depth Priming because a depth "pre pass" already exists in URP and is performed based on your post-processing effects. Depth Priming re-uses/hijacks that pass.

    Priming currently is only enabled when doing so explicitly through the Depth Priming option. Once we get the feature more battle tested we might switch to having it in Auto mode by default but before that we need to fix some issues and have to be sure that this is universally a good thing.

    We force the depth comparison mode to equals for the primed opaque pass (so it deosn't really matter what the shader defines for depth comparison) since the assumption is that the depth in the depth buffer is the exact depth value that we want to shade.
    What CaffeinatedCoolaid suggests is probably the best option. To make your outline shader work with priming you'd have to write out the outline depth as part of the depth prepass. You'd probably also need the depth pass to do multiple shader passes and then you'd end up with the outline depth being included in the post-pro depth which might be undesirable.

    My "try" was a bit vague: we only skip the front-back sorting in the opaque pass atm.
    "try" was playing it safe since since we can't actually skip the front-back sorting in the depth or depth/normals pass for the reasons you've mentioned.
     
  12. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    "opaque" has been mentioned several times here and i admit i haven't looked into alpha tested geometry so far. but i really hope that depth priming will kill the clip command in the forward and deferred passes to enable early depth testing on these. just like in HDRP.
     
    apkdev likes this.
  13. CaffeinatedCoolaid

    CaffeinatedCoolaid

    Joined:
    May 10, 2021
    Posts:
    59
    Oh I feel foolish! I did not realize that it was a whole separate thing, I thought he was referring to the existing depth pass used for the Depth texture.
     
  14. yimingdz

    yimingdz

    Joined:
    Sep 12, 2018
    Posts:
    1
    Hi everyone, I'm trying to add depth priming on urp 7.x. But I 'm confused how do you solve the z fighting caused by depth prepass? Is there some offset for depth prepass so that lately the draw object pass can avoid the fighting artifacts?
     
  15. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    i tried it once – copying the buffer generated for the shadows? well, i do not remember exactly.
    turned out that the matrices were slightly off.
     
  16. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    277
    I'm interested in whether this feature changes anything for clipping on tile-based platforms (where alpha testing was usually discouraged). I noticed that enabling depth priming sets ZWrite to Off and ZTest to Equal on opaque draw calls. Has anyone had a chance to benchmark this yet? Can I go crazy with my alpha clipped vegetation? o_O

    https://forum.unity.com/threads/is-alpha-test-still-the-evil-for-mobile.507024/
    https://forum.unity.com/threads/hlsl-is-there-any-point-to-clip-early.608692/
    https://forum.unity.com/threads/general-questions-regarding-early-z.1065779/
     
  17. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Heya, thing is we have a game that uses A2C based shaders and MSAA for desktop but Depth Priming doesn't run if MSAA is enabled. There's no good technical reason for that as far as I've researched / asked around. Is this a legacy decision that will change?

    As it means dropping our antialiased vegetation for a post effects based solution which changes the look of the game.

    Further question for anyone: Is there a way to force the depth prepass version of the geometry to use a cheaper vertex shader for example we don't want wind in the prepass, as it adds up to being a waste of performance.

    Shader uses shadergraph.
     
  18. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    i haven't looked into URPs depth priming for quite a while... but speaking about HDRP and the depth prepass: using another vertex animation or even none would break the final render. the depth prepass writes out depth, then the regular shader drops alpha testing and uses ZTest Equal which gives you the same result and preserves early depth testing - but only if the final positions match.
     
  19. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I see, I figured that it wouldn't be noticed after a certain distance. So could drop vertex shader cost. I think it's probably better to disguise it and drop it earlier in the main pass then. One of those game rendering problems. Thanks!
     
  20. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    you can fade it out and drop it beyond a certain distance – but you have to do so in both passes.
     
  21. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    241
  22. Tartiflette

    Tartiflette

    Joined:
    Apr 10, 2015
    Posts:
    84
    I was mildly excited when I saw the depth priming feature in URP as I expected it would help me save a lot of performance on badly-sorted alpha-tested geometry (e.g. foliage) on mobile.
    Unfortunately, it looks like all it does is worsen performance in general because it 1) renders depth to a texture, 2) copies the texture into the depth buffer of the main render. Is there no way to get around this? I was hoping such feature would rely on VK subpasses to avoid all the redundant data transfer.
     
  23. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    The behaviour was changed in 2021.2 - what version are you using?
     
  24. Tartiflette

    Tartiflette

    Joined:
    Apr 10, 2015
    Posts:
    84
    I'm using 2022.1 with URP 13.1.8.
    I did just stumble upon an interesting comment in UniversalRendererRenderGraph.cs:
    Code (csharp):
    1. // Current aim of depth prepass is to generate a copy of depth buffer, it is NOT to prime depth buffer and reduce overdraw on non-mobile platforms
    So I guess that's basically it for now :/
     
    apkdev likes this.
  25. DanielWichterich

    DanielWichterich

    Joined:
    Mar 4, 2015
    Posts:
    11
    Are you still interested in reports of visual differences? And where should I report? I have a case where a mesh renders oddly when MSAA is turned on (URP). Its is like I can see through edges, but the mesh is fine - i double checked. By forcing depth priming I can get rid of that.
     

    Attached Files:

    apkdev likes this.
  26. NicoLeyman

    NicoLeyman

    Unity Technologies

    Joined:
    Jun 18, 2019
    Posts:
    33
    Am I correct to assume these artifacts appear where the edges of 2 disconnected polygon edges meet? This could be a precision/determinism issue related to MSAA/depth rendering. Depth Priming could behave a bit better/different from what I remember during development.

    Typically you should report a bug from inside the editor using Help->Report a Bug, share the bug ID and then I can contact the URP team and forward the case to them. But if this is indeed a precision issue there's no real bug to report.
    I'll reach out to the URP team.
     
  27. ManueleB

    ManueleB

    Unity Technologies

    Joined:
    Jul 6, 2020
    Posts:
    110
    Please be aware that depth priming can often reduce performance on mobile platforms, which already benefit from hidden surface removal and similar TBDR GPU optimizations, so depth priming is not really helpful on those platforms.

    upload_2023-1-23_16-41-42.png

    As already noticed in this thread, enabling depth priming introduces additional copy depth passes which are very expensive on mobile/VR.

    If you just need a way to force a prepass without running into the extra cost of additional copy depth, please use:

    Depth Texture Mode - Force Prepass

    upload_2023-1-23_16-43-18.png
     
    Last edited: Jan 24, 2023
    DanielWichterich likes this.
  28. DanielWichterich

    DanielWichterich

    Joined:
    Mar 4, 2015
    Posts:
    11
    The two polygons are connected. This is what makes it so weird. But thanks for your input.
     
  29. NicoLeyman

    NicoLeyman

    Unity Technologies

    Joined:
    Jun 18, 2019
    Posts:
    33
    I'd recommend submitting a bug report then. The URP team couldn't immediately come up with an explanation as well, so it warrants a closer look.
     
    DanielWichterich likes this.
  30. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    I wasn't able to make an object render behind everything else (regardless of its position) until I disabled depth priming. I suspect it ignores shader settings like disabling writing to the z buffer.
     
  31. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    depth priming at least sets ZTest to Equal.
     
  32. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    The fact that it does this silently sucks. Settings that become effectively disabled by some feature being enabled should be at least greyed out.

    Or in the least having some clear documentation/tooltip describing this, which is also not the case for the depth priming checkbox.
     
  33. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    i kind of agree. but actually depth priming has to override the ZTest – at least when it comes to alpha tested geometry. otherwise alpha tested would be as expensive as when not using depth priming (or better: even more expensive).
    it does not have to override the ZTest of any opaque material. but it does.
    ZTest LEqual should be fine with any opaque material and will not result in any overdraw or overshading.
    When it comes to alph atested materials ZTest Equal replaces the clip() command which will make alpha tested materials render at full speed (including early z testing) when it comes to the gbuffers or forward passes.
    a "trick" the addpass shader of the terrain might use as well - instead of doing alpha testing...
     
  34. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194

    Couldn't the depth pre-pass just take into account depth testing settings in the material/shader? If the actual depth pass can, why wouldn't the pre-pass be able to?

    It seems it just ignores it for no reason :/
     
  35. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,873
    it does afaik.
    but then URP overrides ZTest for the "regular" passes like gbuffer or forward. would be nic eit would do so only on materials using alpha testing - just like HDRP does.
     
  36. mahdi_jeddi

    mahdi_jeddi

    Joined:
    Jul 18, 2016
    Posts:
    245
    One of the tricks of Z Priming is to only use some of the bigger meshes that are closer to the camera and not the whole scene (from unity's own optimizations best practices). I don't know why there is no option to set a flag for objects in the scene that would suggest them specifically for this.
     
    minsumandoo and larsbertram1 like this.