Search Unity

CommandBuffer.Clear vs many CommandBuffer

Discussion in 'General Graphics' started by WeltenbauerRenn, Dec 8, 2017.

  1. WeltenbauerRenn

    WeltenbauerRenn

    Joined:
    Jun 20, 2017
    Posts:
    40
    Hello everyone,

    we habe a game that draws almost everything of its environment with CommandBuffers. Currently we create for every Mesh a CommandBuffer and attach it to the Camera when the Mesh should be visible (distance + custom frustum culling). The meshes are sorted in a grid and combined at editor time.

    The profiler show in the Timeline view some small gaps between each buffer.

    My question is: Is it faster to create one or less CommandBuffer that gets cleared every frame and filled up again? Can I maybe help the GPU to group same Materials together or something?

    Thanks for your time.
     
  2. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    I think if you make new ones every frame you are not gaining anything.
    I thought command buffers you create one. Pay the setup cost one time then when playing it back / drawing it is faster.

    I haven't used them much in unity though. Also not sure putting single objects into their own command buffers help either unless it's a really complex object. I think you would put a whole tile of things into one.

    But you should keep researching.
     
  3. WeltenbauerRenn

    WeltenbauerRenn

    Joined:
    Jun 20, 2017
    Posts:
    40
    The current behavior is loading the Mesh and creating a command buffer when it is drawn the first time and destroy the buffer when the mesh is unloaded.

    The idea was to reduce the overhead that comes with gameobjects and components. I can't finde any details how command buffers are used in the unity renderer. If there are copied or just read etc.
     
  4. WeltenbauerRenn

    WeltenbauerRenn

    Joined:
    Jun 20, 2017
    Posts:
    40
    I have made some testing fastest to slowest:
    CommandBuffer.DrawMeshInstanced -> Graphics.DrawMeshInstanced -> MeshRenderer -> Graphics.DrawMesh ->CommandBuffer.DrawMesh

    My test setup:
    A simple diffused shader that takes color parameter. Spawning 1023 GameObjects with MeshRenderer and MeshFilter.
    I clear the CommandBuffer every frame. The GameObjects are disabled when I'm not using them.
    upload_2017-12-14_13-8-51.png

    For me it seems using CommandBuffer is useful for instanced rendering for the rest I'm going to fallback to spawning and pooling GameObjects.
     
  5. daxiongmao

    daxiongmao

    Joined:
    Feb 2, 2016
    Posts:
    412
    I still have the same question, just trying to understand more about command buffers in unity too.

    Why do you need to clear the command buffer each frame?
    I thought a command buffer should be reused.
    https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.html
    Says command buffers can be created and then executed multiple times.
    If you are having to change it every frame I would expect it to be slower due to overhead of having to create/initialize it first.

    I also maybe confusing this with something like directx command buffers which I believe unity's are different.
    While the idea is the same.

    Are you putting all the models in the command buffer?

    What is the difference in the speeds? Are they all close or big differences.
     
  6. WeltenbauerRenn

    WeltenbauerRenn

    Joined:
    Jun 20, 2017
    Posts:
    40
    Yes creating them every frame does give some overhead, but it is not that big as you might thing. I have done a tree system that needs to clear the command buffer every frame (or camera move) and there when doing Instanced draws it its faster than spawning multiple game objects.

    We used to create on CommandBuffer for each Mesh to prevent recreating them. And it turned that creating game objects and just let unity handel it was faster. We gained on some Android devices like 5 ms on the Camera.Render call.

    I'm not 100% sure but I think that you just having a reference to a mesh. When creating a draw call with a CommandBuffer it just a reference to the mesh data on the GPU.

    The difference depends on your data. Keep in mind that when drawing stuff via CommandBuffer it doesn't do culling or z sorting.

    When removing the the clear these are the numbers I got in the editor (2017.2.0p4)

    CPU/Render Thread in ms
    2.4/0.6 : GameObjects with MeshRenderer
    0.4/0.2 : CommandBuffer instanced draw
    2.7/2.9 : CommandBuffer single draw for each object
    0.6/0.4 : Graphics draw instanced
    5.7/0.4 : Graphics single draw for each object
     
    guycalledfrank likes this.
  7. SupriyaRaul

    SupriyaRaul

    Joined:
    Jun 20, 2018
    Posts:
    28
    Hello, I am trying to use command buffers in my Unity project to fetch alternate pixels from my scene and merge them with a checkeboard texture(render the fragment if it's while, else keep the color of pixel as black). I just want help on how to get started with command buffers? Please can anyone guide me?