Search Unity

Why does the renderer render in this pattern?

Discussion in 'General Graphics' started by tylo, Feb 13, 2019.

  1. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    The gif of my problem is too large, so here is a link to it on imgur.

    https://imgur.com/a/Dji28zX

    I am using the Lightweight Render Pipeline, but I noticed that the default renderer also rendered in a very similar pattern.

    The way it is rendering the center of the image first before going outward and doing the edges leads me to believe this is a rendering method that is most use for VR?

    In my case, in this image, all of my meshes are GPU instanced. There are two groups made up of 2048 each. They are 64 meter x 64 meter meshes, which is why it looks "blocky" while being rendered. So, it's 4096 meshes total.

    The left half is one material, the right half is another. The reason it is two materials is due to texture array limitations, but that's unimportant.

    Yet, when I look at the Frame Debugger, the RenderLoop.Draw is not reaching the maximum number of GPU instanced meshes before moving on to another batch of the same GPU instanced material+mesh combo. I believe a maximum number is (by default) around 500, but the Lightweight Render Pipeline is only drawing 373 maximum. Those of you familiar with the Frame Debugger will know that it typically gives a reason as to why a draw call was not batched with its previous draw call, but no explanation is offered in this case.

    Finally, when it's near the end of the RenderLoop.Draw event, I also don't like the order it's doing these renders. It jumps back and forth between the two materials and produces some, in my mind, unnecessary draw calls because of this.
     
  2. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    As an addendum, I did figure out that if I just change the Render Queue on my materials, I can at least control which of my two materials is rendered first in its entirety. Seems like a "duh" thing, but I am still pretty new to this.

    So, now my one material will render in its entirety before it starts rendering the other material (which saves me a couple of unnecessary drawcalls).

    However, I am still running into a weird case where the Lightweight Rendering Pipeline is only batching together 373 of my GPU Instanced meshes. And putting this in my shader does not change that.

    #pragma instancing_options forcemaxcount:500 maxcount:500


    The default values are 500 anyway.

    But, if I switch to the default rendering pipeline, that line in my shader DOES batch up to 500.

    As an extra note, if I put this in my shader, the LWRP does listen to it and only batch things in groups of 10.

    #pragma instancing_options forcemaxcount:10 maxcount:10



    So something must be going on in the LWRP itself to limit my max count to 373 for some reason...
     
  3. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    You don't by chance have a light in the scene?
     
  4. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    I have one, but it's disabled. Also, my shader does not support lights and is an unlit fragment shader.

    I suppose I also have the ambient scene light enabled as well, if that matters.
     
  5. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    The built in renderer has a bug that often it sorts objects depending on lighting even if the shader is unlit. It's possible a similar bug exists in the LWRP. Could be getting sorted by that disabled light, or shadow cacade ranges, or something else, even when it should not.
     
  6. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    154
    Ah, well I figured out my sorting problem was simply that my materials were both the same priority of 2000 (default for geometry). When that is the case, it seems like the renderer can bounce between them willy nilly. By setting one of my two materials to 1999, it always drew the one before the other.

    The bug I am running into now is the batching of 373 items. This only occurs when I am using GPU Instancing and GameObjects. If I use Graphics.DrawMeshInstanced, I get them to batch in groups of 1023 (the maximum that method can handle).

    If I use Graphics.DrawMeshInstancedIndirect, I can draw them in batches of 2048 (which is how many meshes I have per material due to the limit on how large a TextureArray can be).

    Anyhow, in my particular case, all of the above methods are the same frame speed of about 14ms because my bottleneck is the GPU and not the CPU->GPU DrawCall times.

    I am drawing 33.6m triangles and use an AMD RX 580 (equivalent to a GTX 970) so I assume the number of triangles is my bottleneck.