Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

GPU UpdateDepthTexture(directional light shadow) overhead spike when Occlusion Culling enabled

Discussion in 'General Graphics' started by syenet, Sep 8, 2016.

  1. syenet

    syenet

    Joined:
    May 13, 2013
    Posts:
    47
    This issue is related to another post:
    http://forum.unity3d.com/threads/st...ection-in-frame-timing-with-unity-5-4.429704/

    Environment: PC Core i5, GTX 970 Unity 5.4.0f3, forward rendering.

    I have a scene with mixed type directional light casting shadow, and the static scene objects are lightmap baked while dynamic objects like characters are lit and shadowed in realtime. The scene is divided into lots of small blocks, the purpose of this is:
    1. opaque objects can be drawn more accurately in the order of front to back, so GPU can efficiently discard pixel shading if ztest fails.
    2. camera's occlusion culling can be more effective to reduce the GPU's workload.
    From the test result, things work pretty much as expected, except the issue as the title describes.

    First, it seems that the shadowing process of directional light in Unity requires a camera to create a depth texture before rendering the actual objects. The reason seems to be that, Unity need to collect a screen-space shadow texture based on the camera's depth texture and the directional light's shadowmap, and then use this screen-space shadow texture to add shadows in the shadow rendering pass.

    Because of this implementation, Unity forces the camera to execute "UpdateDepthTexture" process regardless of its depthTextureMode. In forward rendering by this implementation, this is necessary because camera truly requires the depth information before the actual rendering, so we can't rely on the native depth buffer which is finished and available only after the actual rendering is over. (I don't know if I understand things correctly, if mistaken, please correct me :) ). So "UpdateDepthTexture" seems inevitable, so its GPU overhead must be accepted.

    Well, the actual issue here is that, at almost any view point in the scene, the cost of "UpdateDepthTexture" becomes higher when I enable the Occlusion Culling.

    For instance, the result of one view point:
    upload_2016-9-8_12-48-36.png
    You can see, the triangle count is hugely reduced when Occlusion Culling is enabled, which is good, and due to less geometry need processing, the cost of culling itself does not lead to much increase in total overhead on the CPU side, all work good.

    But the cost of "UpdateDepthTexture" on GPU side, when with less needs rendering, weirdly increases a lot, and besides, the overhead is very unstable in the profiler comparing to the one with culling off. I don't understand why this is happening, the actual drawcall count of "UpdateDepthTexture" is indeed decreased when culling on, but overhead rises, and I'm pretty sure that's the "Brown Other Section" in Frame Timing profiler of SteamVR:


    Under this circumstance, I gain nothing from Occlusion Culling in most areas of my scene, because with culling off, although a lot more things sent to GPU to render, those which is expected to be culled with culling on, actually turn out being discarded after z-test, so no extra shading involved. As my VR project is typically GPU(fillrate) bound, just process a extra bunch of geometry without shading is not much a big problem.

    So could anyone help explain why occlusion culling is causing the problem? Thanks in advance!