Depth sensor blue texture

Give us as much detail as possible regarding the issue you're experiencing.

Unity Editor version: 2022.2.18f1
ML2 OS version: 1.2.0
MLSDK version: 1.6.0
Host OS: (Windows/MacOS) Windows 11

Error messages from logs (syntax-highlighting is supported via Markdown): No error caught.

Hello I am trying to modify the depth example and read depth only.

This is the code that I am using.

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.XR.MagicLeap;
using UnityEngine.UI;
using System;

public class DepthManager : MonoBehaviour
{
    private readonly MLPermissions.Callbacks permissionCallbacks = new();

    private bool permissionGranted;
    private bool isFrameAvailable = false;
    // private MLDepthCamera depthCamera = null;
    private MLDepthCamera.Data lastData = null;


    // value goes from 0 to 7.5

    public float depthImgMinDist = 0f;
    public float depthImgMaxDist = 7.5f;

    public float ambientRawImgMinDist = 0f;
    public float ambientRawImgMaxDist = 2000f;

    public float confidenceMinDist = 0f;
    public float confidenceMaxDist = 100f;

    [SerializeField, Tooltip("Timeout in milliseconds for data retrieval.")]
    private ulong timeout = 1000;

    [SerializeField]
    private Renderer imgRenderer;
    [SerializeField]
    private Renderer confidenceRenderer;

    private Texture2D ImageTexture = null;

    private readonly int minDepthMatPropId = Shader.PropertyToID("_MinDepth");
    private readonly int maxDepthMatPropId = Shader.PropertyToID("_MaxDepth");
    private readonly int mapTexMatPropId = Shader.PropertyToID("_MapTex");

    private Vector2 scale = new Vector2(1.0f, -1.0f);

    /// Under normal operations long range mode has a maximum frequency of 5fps and a range of up to 5m, in some cases this can go as far 7.5m.
    private MLDepthCamera.Mode mode = MLDepthCamera.Mode.LongRange;

    /// Flags used to specify what kind of data to request from Depth Camera
    private MLDepthCamera.CaptureFlags captureFlag = MLDepthCamera.CaptureFlags.DepthImage;


    [SerializeField, Tooltip("The text used to display error.")]
    private Text statusText = null;


    void Awake()
    {
        permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
        permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
        permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;

        /*cameraModeDropdown.AddOptions(
            MLDepthCamera.Mode.LongRange
        );

        captureFlagsDropdown.AddOptions(
            MLDepthCamera.CaptureFlags.DepthImage,
            MLDepthCamera.CaptureFlags.Confidence,
            MLDepthCamera.CaptureFlags.AmbientRawDepthImage
        );*/
    }

    void Start()
    {
        var settings = new MLDepthCamera.Settings()
        {
            Mode = mode,
            Flags = captureFlag
        };
        // public static void SetSettings(Settings settings) => CurrentSettings = settings;
        // depthCamera = new MLDepthCamera();
        // depthCamera = new MLDepthCamera();
        MLDepthCamera.SetSettings(settings);

        MLPermissions.RequestPermission(MLPermission.DepthCamera, permissionCallbacks);
    }

    void Update()
    {
        try
        {

            if (!permissionGranted || !MLDepthCamera.IsConnected)
            {
                return;
            }

            var result = MLDepthCamera.GetLatestDepthData(timeout, out MLDepthCamera.Data data);
            isFrameAvailable = result.IsOk;
            if (result.IsOk)
            {
                lastData = data;
                // statusText.text += "Data retrived";
            }

            switch (captureFlag)
            {
                case MLDepthCamera.CaptureFlags.AmbientRawDepthImage:
                    if (lastData.AmbientRawDepthImage != null)
                    {
                        CheckAndCreateTexture((int)lastData.AmbientRawDepthImage.Value.Width, (int)lastData.AmbientRawDepthImage.Value.Height);

                        // ambientRawImgMinDist = ambientDepthMin.GetComponentInChildren<Slider>().value;
                        // ambientRawImgMaxDist = ambientDepthMax.GetComponentInChildren<Slider>().value;

                        AdjustRendererFloats(imgRenderer, ambientRawImgMinDist, ambientRawImgMaxDist);
                        ImageTexture.LoadRawTextureData(lastData.AmbientRawDepthImage.Value.Data);
                        ImageTexture.Apply();
                    }
                    break;
                case MLDepthCamera.CaptureFlags.DepthImage:
                    if (lastData.DepthImage != null)
                    {
                        CheckAndCreateTexture((int)lastData.DepthImage.Value.Width, (int)lastData.DepthImage.Value.Height);

                        statusText.text += "Texture created";


                        // depthImgMinDist = depthImgMin.GetComponentInChildren<Slider>().value;
                        // depthImgMaxDist = depthImgMax.GetComponentInChildren<Slider>().value;

                        AdjustRendererFloats(imgRenderer, depthImgMinDist, depthImgMaxDist);
                        ImageTexture.LoadRawTextureData(lastData.DepthImage.Value.Data);
                        ImageTexture.Apply();

                        statusText.text += "Image Texture Applied";
                    }
                    break;
                case MLDepthCamera.CaptureFlags.Confidence:
                    if (lastData.ConfidenceBuffer != null)
                    {
                        CheckAndCreateTexture((int)lastData.ConfidenceBuffer.Value.Width, (int)lastData.ConfidenceBuffer.Value.Height);

                        // confidenceMinDist = confidenceMin.GetComponentInChildren<Slider>().value;
                        // confidenceMaxDist = confidenceMax.GetComponentInChildren<Slider>().value;

                        // AdjustRendererFloats(confidenceRenderer, confidenceMinDist, confidenceMaxDist);

                        confidenceRenderer.material.SetTexture(mapTexMatPropId, ImageTexture);
                        ImageTexture.LoadRawTextureData(lastData.ConfidenceBuffer.Value.Data);
                        ImageTexture.Apply();
                    }
                    break;
            }

            statusText.text = "\nIs frame available: " + isFrameAvailable;
        }
        catch (Exception e)
        {
            statusText.text = e.Message +"\n" + e.ToString();

        }
    }

    private void OnDestroy()
    {
        permissionCallbacks.OnPermissionGranted -= OnPermissionGranted;
        permissionCallbacks.OnPermissionDenied -= OnPermissionDenied;
        permissionCallbacks.OnPermissionDeniedAndDontAskAgain -= OnPermissionDenied;
        DisonnectCamera();
    }

    private void OnPermissionDenied(string permission)
    {
        if (permission == MLPermission.Camera)
        {
            MLPluginLog.Error($"{permission} denied, example won't function.");
        }
        else if (permission == MLPermission.DepthCamera)
        {
            MLPluginLog.Error($"{permission} denied, example won't function.");
        }
    }

    private void OnPermissionGranted(string permission)
    {
        MLPluginLog.Debug($"Granted {permission}.");
        permissionGranted = true;
        ConnectCamera();
    }

    private void ConnectCamera()
    {
        var result = MLDepthCamera.Connect();
        if (result.IsOk && MLDepthCamera.IsConnected)
        {
            Debug.Log($"Connected to new depth camera with mode = {MLDepthCamera.CurrentSettings.Mode} and flags = {MLDepthCamera.CurrentSettings.Flags}");
        }
        else
        {
            Debug.LogError($"Failed to connect to camera: {result.Result}");
        }
    }

    private void DisonnectCamera()
    {
        var result = MLDepthCamera.Disconnect();
        if (result.IsOk && !MLDepthCamera.IsConnected)
        {
            Debug.Log($"Disconnected depth camera with mode = {MLDepthCamera.CurrentSettings.Mode} and flags = {MLDepthCamera.CurrentSettings.Flags}");
        }
        else
        {
            Debug.LogError($"Failed to disconnect to camera: {result.Result}");
        }
    }

    private void CheckAndCreateTexture(int width, int height)
    {
        if (ImageTexture == null || ImageTexture.width != width || ImageTexture.height != height)
        {
            ImageTexture = new Texture2D(width, height, TextureFormat.RFloat, false);
            ImageTexture.filterMode = FilterMode.Bilinear;
            var material = confidenceRenderer.enabled ? confidenceRenderer.material : imgRenderer.material;
            material.mainTexture = ImageTexture;
            material.mainTextureScale = scale;
        }
    }

    private void AdjustRendererFloats(Renderer renderer, float minValue, float maxValue)
    {
        renderer.material.SetFloat(minDepthMatPropId, minValue);
        renderer.material.SetFloat(maxDepthMatPropId, maxValue);
        renderer.material.SetTextureScale(mapTexMatPropId, scale);
    }

    // Update Setting is called after UI update.

    private void UpdateSettings()
    {
        var settings = new MLDepthCamera.Settings()
        {
            Mode = mode,
            Flags = captureFlag
        };

        MLDepthCamera.UpdateSettings(settings);
    }
}

Nothing much changed from the Depth Camera Example. However, after I reference it to a quad, when it is built and ran, its texture is blue.

I did some debugging,

DEPTH_CAMERA Permission is approved.
isFrameAvailable is true which means the data is Ok.
Update is reaching the case MLDepthCamera.CaptureFlags.DepthImage:
ConnectCamera() is being called and the camera is being connected.
The quad is using Magic Leap/Depth Camera Shader.
The quad's Frame Data Map is assigned to an identical texture from the example.
No error was caught in Update.

I am not sure why is it not showing the texture that is being transferred from the depth camera.

How can we fix this?

Hi @hatlabuvic,

Thank you for reaching out regarding this issue. I will try to reproduce this issue. Would you mind providing detailed reproduction steps to create this issue?

Best,

El

Hello @etucker

Here are the steps to reproduce my case.

  1. Create XR Rig in a scene from Packages > Magic Leap SDK > Runtime > Tools > Prefabs
  2. Create an empty game object.
  3. Drag and drop the script ("Depth Manager") that I have provided to the empty game object.
  4. Create an empty object under Main Camera. Make its Z position to be 0.7.
  5. Create 2 quads as children objects of an empty object we just created. They are "Img Renderer" and "Confidence Render". They are scaled to 0.4. Confidence renderer will not be used for this case. Disable Confidence Renderer quad.
  6. Add reference to the script "Depth Manager" like a following picture.
    image
    Status Text can be any legacy text. I used it for debugging.
  7. Enable DEPTH_CAMERA on Project Settings > Magic Leap > Permissions

Once you build it and run it on Magic Leap, Img Renderer should have blue texture and do not render depth information.

Thank you for these detailed steps. I'll go ahead and give this a try and report my findings.

On my first run after following your steps provided, I was able to see the quad but it is white for me. I am not seeing any depth information displayed on it though. I will take a look through the code to see what may be happening.

Does the example project work for you with the DCAM? I would try comparing your code changes to see which changes were made that may have caused this if that is the case. If the example does not work out of the box please let us know.

Hi @hatlabuvic,

Make sure that you are disabling the render that you are not using. The following method assumes that confidenceRenderer is disabled when checking and creating a texture for the imgRenderer

    private void CheckAndCreateTexture(int width, int height)
    {
        if (ImageTexture == null || ImageTexture.width != width || ImageTexture.height != height)
        {
            ImageTexture = new Texture2D(width, height, TextureFormat.RFloat, false);
            ImageTexture.filterMode = FilterMode.Bilinear;
            var material = confidenceRenderer.enabled ? confidenceRenderer.material : imgRenderer.material;
            material.mainTexture = ImageTexture;
            material.mainTextureScale = scale;
        }
    }

To fix this, you can add the target renderer as a parameter. For example:

    private void CheckAndCreateTexture(Renderer renderer, int width, int height)
    {
        if (ImageTexture == null || ImageTexture.width != width || ImageTexture.height != height)
        {
            ImageTexture = new Texture2D(width, height, TextureFormat.RFloat, false);
            ImageTexture.filterMode = FilterMode.Bilinear;
            var material = renderer.material;
            material.mainTexture = ImageTexture;
            material.mainTextureScale = scale;
        }
    }
2 Likes

Your solution worked! It is working! Thank you so much!

1 Like