Sync multiple cameras with ARFoundation

Hi,

I’ m using ARfoundation 2.1.1 with Unity 2019.1.11f1, and I have integrated an outline effect wich uses a second camera attached to the main ARCamera to render only the “outlined objects” layer. The effect works fine, except there is an offset between the render ot the 2 cameras. To be more specific, the outline effect is slightly off the main object render because the 2 cameras are not synced (see the 2 images attached for illustration). The first one is the one taken from my mobile (see the offset between the object and the effect) and the seconds is taken from the editor (where it is fine).

What I tried to solve the problem :

  • Parent the “outline” camera to the “ARCamera” and copying all AR camera components parameters to its child (fov, projection matrix, etc…)
  • Make the second camera an all new ARCamera with all necessary components (tracked pose driver, arsessionorigin, arcamera manager).
  • And many combinations of the 2 previous main solutions…

Results are still the same any way the offset between the effect and the object remains.
My observation is that the offset increases when the object is closer to the fov limits (border of the screen).
I think I’m missing something about the way the ARCamera works. If you have more informations about this…

Thanks in advance for the help,

Thomas


1 Like

I too have suffering from this problem. I’ve got a second camera that uses some depth masking objects to reveal rendered elements of the camera beneath it, but they are offset exactly has described and shown in the images above.

OK I just came up with a solution.

Attach the script below to the any cameras parented to the ARCamera and they will stay synced up with it during rendering. I have no idea which one of the properties being copied over is actually causing this to work, because its 1:30 AM and I needed to get this solved for a client demo meeting later today.

using UnityEngine;

[ExecuteAlways]
public class ARCameraMatcher : MonoBehaviour {
    public Camera sourceCamera;

    private Camera _myCamera;

    private void OnEnable() {
        _myCamera = GetComponent<Camera>();
    }

    private void OnPreRender() {
        if (_myCamera == null) {
            return;
        }
        if (sourceCamera == null) {
            return;
        }

        _myCamera.nearClipPlane = sourceCamera.nearClipPlane;

        _myCamera.farClipPlane = sourceCamera.farClipPlane;

        _myCamera.orthographic = sourceCamera.orthographic;
        _myCamera.orthographicSize = sourceCamera.orthographicSize;
        _myCamera.fieldOfView = sourceCamera.fieldOfView;

        _myCamera.cullingMatrix = sourceCamera.cullingMatrix;
        _myCamera.nonJitteredProjectionMatrix = sourceCamera.nonJitteredProjectionMatrix;
        _myCamera.projectionMatrix = sourceCamera.projectionMatrix;
        _myCamera.useJitteredProjectionMatrixForTransparentRendering = sourceCamera.useJitteredProjectionMatrixForTransparentRendering;
        _myCamera.worldToCameraMatrix = sourceCamera.worldToCameraMatrix;

        _myCamera.stereoConvergence = sourceCamera.stereoConvergence;
        _myCamera.stereoSeparation = sourceCamera.stereoSeparation;
        _myCamera.stereoTargetEye = sourceCamera.stereoTargetEye;

        _myCamera.sensorSize = sourceCamera.sensorSize;
        _myCamera.gateFit = sourceCamera.gateFit;
    }
}
2 Likes

Thank you @ryancookyeti ,

You solved the problem with OnPreRender method.
I suspected the projectionMatrix parameter to be the solution but I made the change in the Update method before.
Now it works perfectly.

So here the final script to attach to the child camera :

using UnityEngine;

[ExecuteAlways]
public class ARCameraMatcher : MonoBehaviour
{
    public Camera sourceCamera;

    private Camera _myCamera;

    private void OnEnable()
    {
        _myCamera = GetComponent<Camera>();
    }

    private void OnPreRender()
    {
        if (_myCamera == null)
        {
            return;
        }
        if (sourceCamera == null)
        {
            return;
        }
        _myCamera.projectionMatrix = sourceCamera.projectionMatrix;

    }
}
3 Likes

Man… @ryancookyeti and @Thomas_Toys ya’ll are awesome. I was up till 3am last night trying to figure this out. Worked on first try. Thanks!!!

you guys are genius, thanks a lot

This is just what I wanted. Thanks you so much guys!!!