Flickering when using Immediate Mode Shapes with an Overlay camera in URP

Avatar
  • updated
  • Fixed

I've been having a lot of difficulty lately with shapes drawn in Immediate Mode flickering, over-drawing (rendering multiple times), and sometimes just not drawing at all. I've managed to isolate the flickering and over-drawing to a standalone project that can be downloaded below:

Here is a download link to the project files

Image 357

Repro steps: 

  1. Open the project in Unity 2020.3.2f1
  2. Open scene at/Bug/Scenes/SampleScene
  3. Hit play
  4. The above flickering should be seen.

The flickering seems to come from some elements being drawn more times than they should be. Ideally, there should be only 5 draw commands for the HUD elements, but for some reason it's 7 here. The frame debugger can also act a bit strange, flickering even while scrolling through the list of elements. In extreme situations (not visible here, but it is in my main project) it can re-order elements so dramatically it will make the frame debugger unusable since every click goes somewhere different. When no flickering or overdraw is present, this behavior does not occur.

Image 365


To give an idea on the architecture of the scene, here's what's happening:

1. The left and right displays are being rendered with the help of a screen space canvas to use as reference for positioning. Both the canvas, and the Immediate Mode Shapes that are drawn on the canvas, are rendered to an overlay camera called ShapesHUDCamera. The RenderCoolThing component on the HUDCanvas draws these two shapes. There is nothing wrong these as far as I can tell. They render just fine under normal circumstances.

It's worth noting that the ShapesHUDCamera happens to be coincident with the main camera. In the real project, this is not the case. The ShapesHUDCamera stays at the origin while the main camera can be anywhere. The guard clauses to render specific shapes to specific cameras are also necessary because not all cameras should see all Shapes elements. Otherwise situations like this can result.

2. In the 3D world, there is an Immediate Mode disc being drawn on top of a cube. This drawing is handled by the StrategicRenderer object, with the StrategicSymbols Monobehaviour.

A weird workaround?

In the process of trying to recreate this bug from my main project, I have noticed something strange. The flickering can be fixed by either drawing all Shapes to the same camera, or by switching the cameras that the Shapes are being rendered to.

To do the former:

  1. Select the HUDCanvas object
  2. Change the Canvas' Render Camera to MainCamera
  3. Change the RenderCoolThing component's DrawCamera to MainCamera
  4. Run the game

Image 358

Somehow it works perfectly now?

Image 359

Putting everything on the same camera does admittedly make some kind of intuitive sense. We can get weirder though. At first, I thought that the cause of the problem was rendering Shapes to an Overlay camera, but for some reason if the disc is drawn on the overlay camera, but the HUD shapes are drawn on the main camera that works too? I'm not sure why one would work and the other doesn't.

  1. Follow the steps above to put the HUD onto the main camera
  2. Select the StrategicRenderer object and set its RenderCamera to the ShapesHUDCamera
  3. Hit Play
  4. No flickering or overdraw, even though they are rendered to different cameras

Image 360

Image 362

    Reporting a bug? please specify Unity version:
    2020.3.2f1
    Reporting a bug? please specify Shapes version:
    3.2.3
    Reporting a bug? please specify Render Pipeline:
    URP
    Pinned replies
    Avatar
    Freya Holmér creator
    • Answer
    • Fixed

    this has now been fixed in 4.0.0

    Avatar
    Brian

    Okay so here's something I noticed that can cause flickering, because it just happened in my main project but then I was able to fix it. I was in the callback for one camera's beginCameraRendering, but drawing to another camera.

    I know I was in a different camera because I was doing a check to see is it this camera X but then drawing to camera Y instead.

    By changing the check to be is this camera Y, and drawing that shape only in the callback for that camera, and then the camera X stuff in its own callback, it stopped the flickering the camera Y shape code caused.

    This may or may not be related to the bug, but I didn't know that you needed to be in the same callback as the one you are sending draw commands to. Though, It does make some intuitive sense.

    Avatar
    Freya Holmér creator
    • Planned

    just commenting to say that this is the most prioritized thing to fix for the next version, thanks for the details

    I'm still recovering from surgery, so it might take me a while before I can get it done I'm afraid

    Avatar
    Freya Holmér creator
    • Answer
    • Fixed

    this has now been fixed in 4.0.0