Search Unity

SSAO and GPU Instancing

Discussion in 'General Graphics' started by hardcorebadger, Jul 8, 2018.

  1. hardcorebadger

    hardcorebadger

    Joined:
    Nov 28, 2016
    Posts:
    31
    Hey there!

    I'm interested to understand exactly how an SSAO image effect would affect an instanced shader. I've gotten an instanced shader to reduce my draw calls by A LOT, which helped A LOT with performance. After that i go to turn on unity's SSAO and see my draw calls go way back up, and slow down a lot. With the frame debugger I could see all my objects were no longer in big batches, so I assumed case closed, SSAO just requires you to not batch everything.

    This was until I got SSSAO from the asset store - which was apparently a lot faster. I throw this one on, and again see my draw calls go way up, but the weird thing this time is my tick didn't slow down at all. This really started to confuse me, as seeing way more draw calls should (to my understanding) increase the tick time. This left me basically having no clue how anything worked all over again.

    So I know SSAO is an image effect on the rasterized pixels after all the painters algorithm stuff has happened. I THOUGHT draw call batching basically saved the GPU from having to "switch brushes" so to speak, that switch taking a lot of time, and hence batching decreasing the time total. Not sure how GPU instancing works at all.

    Furthermore, I've noticed sometimes when I switch the image effect on and off, it doesn't just drop the draw calls back to what it was before - I have to restart to get it to fix.

    All this together just makes me confused about what is actually going on here - so any advice on what really goes on / how these things work / how they might interact would be awesome!

    Thanks!
     
  2. JackieDevelops

    JackieDevelops

    Joined:
    May 11, 2017
    Posts:
    27
    GPU instancing in the default Unity implementation involves filling out a buffer with all the data that is unique to each instance, and then having each instance index into that buffer to get that data. The pipeline state is constant, in that we dont have to bind a different vertex/pixel shader, and we dont need to change the vertex buffer. Without GPU instancing, we would at least need to update the constant buffer bound to the pipeline to insert the unique information per material, but GPU instancing combines all that unique information into 1 buffer and in doing so doesnt need updating and allows Unity to use the DrawInstanced API from the respective graphics library that it uses.

    Thats at least my understanding of the technical aspect of GPU instancing. Now why this breaks when you use SSAO... I have no idea. In my mind, these two are completely unrelated. I guess one question would be, what rendering path are you using? SSAO needs a depth buffer at the very least, and preferably a normals buffer of the rendered scene as well (at least for most of the SSAO implementations that I am aware of).

    Also, you mention batching. Are you relying on dynamic batching or GPU instancing? These are different things. I believe in Unity, dynamic batching is the act of grouping together small meshes into a larger mesh on the CPU, so long as the gameobjects with those meshes share the same material. GPU instancing is the act of being able to render multiple gameobjects that use the same mesh/same shader all in 1 call.

    I would be very interested to find out how your problem manifests.