How to stop real surfaces from covering up AR surfaces

As developers of AR apps, we often want to overlay a virtual mesh, object, or surface over real surfaces, but in some circumstances, we find that reality is taking precedence over our hard work. A term to describe this behavior would be z-fighting or plane-fighting. Thankfully, the solutions below are quick and easy to implement.

Solution 1: Sorting Layer

The easiest solution can be found from within the editor in the Inspector window. Sorting Layers are configurable, easy to locate, and easy to understand. Lower numbered layers are rendered before higher numbered layers. Changing your AR object to use a higher numbered layer than the default one might fix the z-fighting issue.

Solution 2: Render Queue

Unity’s RenderQueue enumeration within Material and Shader determine when an object is rendered on the screen. Lower numbers in the queue are rendered before higher numbered queue members. In fact, this solution is as easy as selecting the material or shader of the AR mesh you would like to overlay and updating the Render Queue from within the editor.

Render Queue must be a whole number between 0 and 5000 – bounds are inclusive. To use the Render Queue provided by the shader the material is attached to, supply -1.

Solution 3: Sorting Order

Unity’s Renderer component includes a “sortingOrder” integer member which determines how objects within the same Sorting Layer are displayed. Objects with a lower sorting order are displayed below objects with a higher sorting order. While some elements like the Canvas include a “Sort Order” property from within the Inspector, most game objects will require you to update the sort order from a script.

public void Start()
    // Let's fetch the Renderer component of our GameObject and update the
    // sorting order to be a higher number than the default 0.
    Renderer renderer = gameObject.GetComponent<Renderer>();
    renderer.sortingOrder = 5; // Must be between -32768 and 32767.

Note: Property updates demonstrated via the Inspector in previous solutions are also exposed through the Renderer component.

Like most problems in game development, there are many different solutions you could employ to solve an issue like this. The above solutions are just a few examples of what you could try to get the result you’re looking for.

1 Like

Hi Maverick,

I went through all of the three suggested solutions without noticing a different result between the VPS Mesh and the instantiated anchors.

But I discovered in the Mockup Scene that by setting the Key Frame Frequency (under ARSceneCamera → AR Depth Manager (Script) component) that the flickering disappeared when the Key Frame Frequence matches the FPS of the scene and when Interpolation is set to None!

I tried to match the FPS (30) when using the app at the Private Scan Location, but that did not change anything though.

Could there be something about the AR Depth Manager that needs to be adjusted to get it to stop flickering?

Sincerely, Pontus Jakobsson

Just one note that I discovered about the Solution 2: Render Queue when using the Universal Render Pipeline, according to URP Documentation the Sorting Priority should have the same function as earlier Render Queue.