Black lines between objects when using orthographic camera

I have a main camera set to orthographic and a cinemamachine camera with targeted group that I use to achieve isometric perspective and keep the playable area visible on different mobile devices.
The problem is that on some devices, especially on my phone there are visible black lines between the cubes that make up an arena.


Why is this happening and how to fix it?

This is not related to Cinemachine, I’ve removed the tag.

I figured out that these are gaps between cubes that are being displayed, but I don’t understand why the are showing up, because I am using a script that spawns cubes each next to eachother:
using UnityEngine;

public class Arena : MonoBehaviour
{
    [SerializeField] GameObject ArenaBlock;
    [SerializeField] int size = 10;
    void Start()
    {
        SpawnArena();
    }

    void SpawnArena()
    {
        int colNumber = 0;
        for (int i = 0; i < size * size; i++)
        {
            colNumber = i % size;
            Vector3 location = new Vector3(colNumber - 5, 0f, (i / size) - 5);
            GameObject block = Instantiate(ArenaBlock, location, Quaternion.identity);
            block.transform.SetParent(transform);
        }
    }
}

Turning on the anti-aliasing reduces the gaps visibility, but doesn’t remove them
entirely. Another thing I noticed is that the gaps appear after a few seconds of the game being played, at the start there are none.

I doubt that they are gaps. It could be microgaps since you change the parent after positioning them. When you parent an object, it’s position has to be recalculated since it is now relative to the new parent.

However the reason for those things is usually related to z-fighting of the side faces of the cube(s). z-fighting is influenced by a couple of things like the resolution of the z-buffer, how close the faces are rendered to the camera (as the depth buffer is non-linear) and the “range” of the depth buffer which is determined by the difference between the near and far plane of the camera. The larger the viewable area, the less accurate the depth buffer gets.

Most voxel games like minecraft construct only the visible faces of cubes which make up the world. This avoids this problem as two adjacent solid cubes would not have side faces generated where the cubes meet.

To position the cubes reliably inside the parent, you probably want to set localPosition after you called SetParent. That way you actually position the objects inside the local space of the parent where they actually end up. Though because of the other things I’ve mentioned, the issue may not go away. Where and when z-fighting happens depends on many things. So even when it looks like the problem may be solved, it may come back when you’re a bit closer or when you have a slightly different angle or position.

ps: I just realised that you use an orthographic camera. They usually use a linear depth buffer. However you may still run into issue when the range is too large. The range is “(zFar - zNear)”.