Search Unity

Poor performance of UpdateDepthTexture - why is it even needed?

Discussion in 'Editor & General Support' started by Dolkar, Aug 25, 2013.

  1. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    So, I need to render a bunch of unlit objects and read from the depth texture afterwards (on a GPU) as fast as possible. The problem is, when I do the most logical thing, set the camera's depthTextureMode to Depth, the UpdateDepthTexture process takes significant amount of time. Not to mention batching breaks completely, so the vast majority of draw calls are spent on this.

    From what I understand though, there should be absolutely no need to render the depth to a separate buffer. You should be able to read the depth component of the FBO straight from a shader. Indeed, this is mentioned in the docs as well: "In some cases, the depth texture might come directly from the native Z buffer.". So, is there any way to force this, targeting for Direct3D?

    There seems to be no technical limitation, because the Unity's deferred rendering path must make and read from the depth buffer as well, yet there is no such UpdateDepthTexture component present in the profiler.

    Thanks for any and all help!
     
    Last edited: Aug 25, 2013
  2. spraycanmansam

    spraycanmansam

    Joined:
    Nov 22, 2012
    Posts:
    254
    Hi Dolkar,

    Interesting you're having this problem. I was just about to start a similar themed thread...

    We have been experiencing similar issues. At first I had thought it might have been my camera setup/shaders, but after extensive testing, anything that seems to 'signal' to Unity (including built-in post-fx) that it needs the depth texture starts it generating the 'UpdateDepthTexture' / 'UpdateDepthNormalsTexture' processes.
    It's absolutely smashing performance for us, with those processes generating anywhere around 500 drawcalls each and doubling the reported tri count.
    Switching to deferred rendering softens the blow a little, because like you say, it automatically creates the depth buffer as it goes. In forward mode, it seems there is no depth buffer being rendered until it's needed by a shader, and then BAM, major performance hit.


    Interesting you mention about the batching not working as well, as the other half of BEAM Team has been experienced trouble with that and now I'm thinking they're related...


    I think it's safe to say that we would both appreciate if some Unity gurus weighed in on this one!
     
  3. Ben-Massey

    Ben-Massey

    Joined:
    Jun 13, 2011
    Posts:
    581
    Thought id add some of the crazy profiler spikes that are clearly out of proportion. (right click large)
     
  4. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Short answer: you're right, we should fix that (we haven't yet).

    Longer answer: it's a bit complicated, especially once you go into areas of non-fullscreen cameras (e.g. split-screen). Say a camera renders into part of a screen, but if you were to sample the Z buffer texture naively, you'd get the texture of the whole screen. And then there are cases where platforms don't support reading from the Z buffer at all (GLES when no GL_OES_depth_texture is exposed; or Direct3D9 when no INTZ hack is present in the drivers; or desktop GL on Mac with some buggy Radeon drivers etc.).

    For the moment, producing a depth texture means a separate rendering pass; unless you're using deferred rendering (where the depth texture is a byproduct of the base geometry pass anyway).
     
  5. metaleap

    metaleap

    Joined:
    Oct 3, 2012
    Posts:
    589
    Am really hoping for native Z-buffer reads for current-gen high-end (and next-gen mid-range) mobile devices in GLES 2.x at least wherever GL_OES_depth_texture is supported. The major current-gen mobile GPUs mostly seem to support it, so if SystemInformation.Supports(depthTexture) then _cameraDepthTexture should map to it without almost doubling draw-calls. (Could still fall back from the z-buffer approach to the render-texture approach if multiple cams are active that are directly rendering to the screen.)

    Maybe this is already the case? I have no way of testing it: the GL ES 2.x emulation in the Editor's Game View does almost-double draw-calls when _cameraDepthTexture is used, however maybe that's a "lowest-common-denominator" emulation and GL_OES_depth_texture is indeed interpreted by the engine on-device? If I push to a highly performant Android phone I can't notice a drop in FPS yet but I don't have too much going on yet in the scene and sadly there's no public variable "numDrawCalls" that Unity simply increases for each of its internal gl.DrawXyz() calls it's doing...

    We could do some amazing effects in our post-fx shaders and really raise the bar on mobile if we had access to depth without doubling draw calls (or going Deferred, which amounts to the same)! I'd be fine with manually checking for depth-texture support at runtime and disabling some effects, but I'd still need to know whether _cameraDepthTexture if used would be mapping the z-buffer or not...

    Maybe this is planned in 4.3? Or maybe indeed like the Unity docs hint, when a native z-buffer is supported then the _cameraDepthTexture sampler actually reads from that directly, and it's just not present in GL ES emulation? (Still get double-drawcalls even with emulation-off though, using -force-opengl -- though docs say with OpenGL the _cameraDepthTexture always represents the native z-buffer....)
     
    Last edited: Oct 30, 2013
  6. akutruff

    akutruff

    Joined:
    Jul 24, 2009
    Posts:
    44
    I don't even need to do anything in a shader with the depth value - I just want the z test to be preserved after a post fx. I blur the screen, and then I want to draw some things on there but I want the z test to succeed or fail based on what should be in the depth buffer.

    I've spent a good two days trying to get another camera to draw on top of blurred main camera without having to use a second pass generated depth texture.

    From forum hunting this topic has been raised a lot, and there really is no resolution as far as I can tell.

    It's terribly frustrating when it sounds like GLES 2.0 can just let the second camera use the z buffer that is already there.

    Is there any way to just let a second camera just draw on top of a render texture without doing that second depth pass? I hope so since it's been a while.
     
    Last edited: Feb 26, 2015
  7. reckert

    reckert

    Joined:
    Aug 17, 2015
    Posts:
    1
    I just came across this problem trying to implement some image effects for a mobile game I'm working on.
    It seems like this still hasn't been fixed in Unity 5.1.2 or am I doing something wrong? I tried the built in Depth of Field effects to compare but as soon as I enable any effect that requires a depth texture my drawcalls are pretty much doubled. We're already struggling to reduce the number of drawcalls so this really isn't acceptable.

    I could get around this by writing the depth to a second RenderTexture on platforms that support MRT or maybe I could somehow get access to the actual Z-Buffer using a native rendering plugin.
    But that's not exactly what I would call an ideal solution...
     
  8. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,738
    Wow is it really still the case? UpdateDepthTexture is super slow on iOS and the extra pass ignores any batching.

    What is the proper method to be able to use GL_OES_depth_texture on iOS? (Is it even possible? The manual seems to think so)
     
  9. SixpenceChen

    SixpenceChen

    Joined:
    May 14, 2015
    Posts:
    3
    It is still the problem about depthTextureMode in 5.1.3.

    I set the camera's depthTextureMode to None, but UpdateDepthTexture render pass always work.

    I have two cameras, one need camera depth texture, the other one don't need. How can I work with it?
     
  10. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    @Aras UpdateDepthNormalTexture is still ignoring batching at all.
    In my case 691 batches for UpdateDepthNormalTexture and only 249 for drawing the same geometry with batching.
    Is there any way to optimize it on my side?
    (Target platform AAA PC Unity 5.3.1f1)
     
  11. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I see - I was wondering where I was losing perf and it checks out. I'm hoping this will get done sooner rather than later so that the cinematic image effects can potentially be optimised for forward too. Or any forward+ that happens.
     
  12. DanielShi20

    DanielShi20

    Joined:
    Aug 22, 2016
    Posts:
    1
    I came across the same issue. Does it be fixed in 5.4 version ?
     
  13. amarchal

    amarchal

    Joined:
    Nov 19, 2014
    Posts:
    3
    I'm looking around for a solution as well. I am on 5.4 and i don't see anything that will address having to render a geo prepass in forward to get a depth texture, am i missing something? This takes one of the nice things about the forward renderer(speed) and kicks it in the shins.
     
  14. ChayChay

    ChayChay

    Joined:
    Sep 10, 2014
    Posts:
    12
    Is anyone else seeing a big jump in the draw calls in the UpdateDepthTexture pass after updating to 5.4? Just went from 5.3.5 and around 200 calls (using profiler) to 5.4.0 and around 3000 reported calls. Is this bad? Can it be fixed? I thought 5.4 would preform better but I'm not seeing any improvement in our framerates...
     
    buronix likes this.
  15. kalineh

    kalineh

    Joined:
    Dec 23, 2015
    Posts:
    241
    I was digging around this topic and I though I'd just add my findings; having any shadows enabled in forward rendering causes a UpdateDepthTexture pass to be added. The range is based on camera farClipPlane, even if the shadow render distance is very short. For depth buffer used by forward rendering shadows specifically I think the farClipPlane could be reduced and save a ton of render time (2-3ms of our 11ms~ VR frame time). I can't find any way to hook/hack the camera passes to modify the farClipPlane for just the UpdateDepthTexture pass sadly. Maybe the new ScriptableRenderLoop will give better control over this.
     
  16. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    Yes, new scriptable render loops will give more control over this.

    Under Edit -> Project Settings -> Graphics there's a way to turn off cascaded shadow maps for directional lights, which should remove this depth texture pass in forward rendering. I forget whether that got added in Unity 5.4 or 5.5.
     
  17. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    If you have a lot of static batched objects, then yes, we just found a bug where 5.4, especially during depth pass, could result in more draw calls than before. This is being fixed as we speak and should reach 5.4.x patch releases shortly.
     
    ChayChay and fffMalzbier like this.
  18. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    I believe I am still seeing this in Unity 5.5. I have a scene with 9 cubes made up of individual quads, so 54 game objects total. The sides are colored randomly with 2 materials, and static batching is activated.

    The cubes are drawn with two draw calls everywhere, except for the UpdateDepthTexture / DepthPass.Job that uses 18 Draw Calls with no grouping that I could make sense of. Seemingly, quads with the same material are randomly drawn together sometimes, and sometimes not.

    Please note that I'm not using submeshes, which make the number of draw calls (not state changes, i.e. what Unity shows as batches) explode, but real individual meshes.
     
  19. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,372
    I have this problem too. UpdateDepthTexture nearly doubles my drawcalls. This only happens in forward rendering but no shadows are present. Tested with 5.5
     
  20. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    So scriptable render loops, fixing this or?
     
  21. pew_tom

    pew_tom

    Joined:
    Jan 20, 2017
    Posts:
    2
    We are also seeing this issue in 5.5.0 (UpdateDepthNormalTexture is still ignoring batching).
     
  22. G1NurX

    G1NurX

    Joined:
    Dec 25, 2012
    Posts:
    69
    Issue still exists in Unity 5.6
     
  23. PieterAlbers

    PieterAlbers

    Joined:
    Dec 2, 2014
    Posts:
    245
    Any news on this?
    Stuck with hundreds of additional drawcalls :(
     
  24. BearHugMark

    BearHugMark

    Joined:
    Feb 21, 2016
    Posts:
    21
    Same here. I have this super nice volumetric ground fog working on the device, but it's double draw calls so can't really use it. It's a shame, cos I have a perfectly good depth buffer sat there that I can't access. Any updates? Would be SO SO handy to have this.
     
  25. PieterAlbers

    PieterAlbers

    Joined:
    Dec 2, 2014
    Posts:
    245
    I can't understand why this thread is not more active, especially since this one was create almost 4(!!!) years ago - we're probably not the only ones experiencing this.

    What are we missing? Is this too hard to fix? What is going on?
     
  26. HarryCodder

    HarryCodder

    Joined:
    Feb 20, 2015
    Posts:
    84
    I could not find a bug report about this in the issue tracker, might be a good idea to make one.
     
  27. Elecman

    Elecman

    Joined:
    May 5, 2011
    Posts:
    1,372
    The problem is still present in Unity 2017.1.0f2

    If an image effect which causes the camera to render a depth texture is disabled, the camera keeps rendering a depth texture. You need to disable this manually:
    Code (CSharp):
    1. Camera.main.depthTextureMode = DepthTextureMode.None;
    This should be done automatically in Unity though. But the excessive amount of batches should be fixed too.

    Bug report with repo filed. Case nr 934154

    Edit:
    I got a reply from the QA team stating that my bug report is a duplicate from the one here:
    https://issuetracker.unity3d.com/is...me-debbuger-after-baking-realtime-point-light
    So please add a vote to get this fixed sooner rather than later.
     
    Last edited: Jul 24, 2017
  28. eastes

    eastes

    Joined:
    Sep 1, 2012
    Posts:
    59
    I just nearly halved my tris and draw calls with the script to disable depth texture. Thanks @Elecman !
     
  29. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    390 DrawCalls for drawing the scene normally in Drawing
    277 DrawCalls for UpdateDepthTexture... combined they are less than 1000, which is okay
    1893 DrawCalls for drawing the UpdateDepthNormalsTexture ... what the heck?

    2017.3.1p1

    Edit:
    Disabled the Postprocessing Behaviour (Stack). Draw Calls dropped way below 1000.
    Why is rendering with a replacement pass to get the DepthNormalsTexture (which the Stack is doing) so slow in comparison to regular Drawing?
    It looks like batching is not even half as efficient in that case. Or is it? And I am seeing some other sideeffects here?
     
    Last edited: Feb 20, 2018
  30. noio

    noio

    Joined:
    Dec 17, 2013
    Posts:
    230
    Seeing exactly the same behaviour here. Is there a reason that UpdateDepthNormalsTexture doesn't apply batching..? I've been so careful not to break batches, and now this! Hahahaha :eek:
     
  31. Glader

    Glader

    Joined:
    Aug 19, 2013
    Posts:
    456
    Has this ever been addressed in 5.6 or any version? Still seeing insane amounts of drawcalls due to depth stuff in the frame debugger. I have a scene with hundreds of chunked static pieces using the same material. This is killing things.
     
  32. PieterAlbers

    PieterAlbers

    Joined:
    Dec 2, 2014
    Posts:
    245
    afaik this has never been addressed - and I don't think it will ever be.
    Especially with the new render pipelines currently in development.

    Any reply from Unity would be appreciated though....
     
  33. GilFerraz

    GilFerraz

    Joined:
    Jul 4, 2016
    Posts:
    7
    Is there any confirmation if the new SRPs will give us control over this or not?
     
  34. Kusras

    Kusras

    Joined:
    Jul 9, 2015
    Posts:
    134
    Wow, so importnat issue 5 years later and what I can find is only this thread... so they did not fixed it yet in Unity 2018?
    I experience 9400 drawcalls from this pass in contrary to 800 other passes drawcalls and ofc I want to optimise it!
     
  35. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    SRP is the answer, yeah. It's unlikely to be "fixed" in the classic renderer as far as I know because there is no point to that. The replacement and future is SRP (LW/XR/HD) and they give you control.

    Probably because the "fix" is SRP.
     
    NeatWolf likes this.
  36. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    This issue exists for a long time already and it's not going to be fixed for the "Legacy Renderer" anymore.

    Enabling 'DepthNormals' on the Camera causes Unity to not batch any draw-call during UpdateDepthNormalsTexture in Forward Rendering. Batching does work in DeferredRendering though.

    I submitted a bug-report for this issue in July 2017:
    (Case 924489) Draw-call batching not working during UpdateDepthNormalsTexture

    The bug-report has been closed and Unity Technologies are not going to fix it anymore. Here is the reply I got from Unity QA:
     
    Last edited: Mar 13, 2021
  37. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    Unity, this is a f joke. 2021 and still this bug. Seriously?
     
    Last edited: Feb 18, 2022
  38. Kusras

    Kusras

    Joined:
    Jul 9, 2015
    Posts:
    134
    I never used SRP, I think it means I have to rework anything and then do some custom scripts to batch it... I am not sure that everyone need SRP, And if this means some serious performance issue I do not understand, why they do not fix it if it is still default project settings. And could be close to copy paste the logic from other passes or not?

    Anyway found someone any manual how to fix it in SRP?
     
    Last edited: Apr 2, 2021
  39. HASSANHR

    HASSANHR

    Joined:
    Feb 23, 2018
    Posts:
    18
    it's 2022 and i had to break my head on the wall for 3 days, to find out that depthTextureMode on camera was causing my Drawcalls to Double 2X !!!!!
     
  40. agauger28

    agauger28

    Joined:
    Jun 20, 2020
    Posts:
    17
    Bump, Feb 2022.
     

    Attached Files:

  41. bfoddy

    bfoddy

    Joined:
    Mar 27, 2012
    Posts:
    85
    Yeah this should be fixed for BIRP, given that SRPs are really still not production ready for many types of games
     
    Marco-Sperling likes this.
  42. ZenTeapot

    ZenTeapot

    Joined:
    Oct 19, 2014
    Posts:
    65
    bump... just encountered this today. really...
     
  43. ionutbaza26

    ionutbaza26

    Joined:
    Jul 21, 2022
    Posts:
    3
    Yep, its terrible. Deferred seems to be the only way when using core rendering.
     
  44. Marco-Sperling

    Marco-Sperling

    Joined:
    Mar 5, 2012
    Posts:
    620
    2023, builtin RP is still a thing and widely supported by many assets on the store... just Unity is giving us the middle finger
     
  45. ionutbaza26

    ionutbaza26

    Joined:
    Jul 21, 2022
    Posts:
    3
    100%. Built in is just superior in every single way. From build times, to performance, to app support, to ease of use.
     
  46. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,756
    And you forgot memory usage. URP in mobile RAM usage is a joke.

    But I think Unity won't bother fixing this issue if after 4 years they haven't. Maybe they want to use this bug as proof that URP is faster than built-in lol. I mean, you make it suck as much as possible so you can sell your new product.