Unity RenderTexture Black when Saving PNG on Oculus Quest/Android

Hi, I’ve scoured the web for a possible solution to my problem with no avail.

I’m currently trying to add a screenshot function on the Oculus Quest where a player can take a picture from a secondary camera.

When I run my program from the editor, with the exception of lag from taking the picture, it works perfectly fine. However, when I push to app lab to run on the Oculus natively, I always get a blank image. I’ve messed around with the color encoding, flag settings, and using OnRenderImage.

I’ve also tried several encoding options, so I think the problem lies in the RenderTexure.

Apparently, having black images or RenderTextures is a common problem with Android or mobile devices, and I’ve seen some threads on them. As the Quest is an Android based device, I tried as many suggestions as I could find to no avail.

Here’s one of the threads I looked at:
https://stackoverflow.com/questions/35196619/render-texture-black-on-android-only

If anyone has a clue to what may be wrong, I’ll be very grateful to hear your suggestions.

Below is the section of code responsible for taking the picture.
Thanks!

    private IEnumerator TakePhoto()
    {
       
        yield return new WaitForEndOfFrame();
        string sceneName = SceneManager.GetActiveScene().name;
        if (sceneName.Equals("HomeScene"))
        {
            cameraFlash.SetActive(true);
        }
        Camera cam = cameraTransform.GetComponent<Camera>();
        RenderTexture renderText = RenderTexture.active;
        cam.Render();
        RenderTexture.active = cam.targetTexture;


        Texture2D Im = new Texture2D(cam.targetTexture.width, cam.targetTexture.height, TextureFormat.RGB24, false);

        // adding wait here, makes error
        Im.ReadPixels(new Rect(0, 0, cam.targetTexture.width, cam.targetTexture.height), 0, 0);
        yield return new WaitForEndOfFrame();
        yield return new WaitForEndOfFrame();
        Im.Apply();
        yield return Im;

        byte[] Bytes = ImageConversion.EncodeArrayToPNG(Im.GetRawTextureData(), Im.graphicsFormat, (uint)cam.targetTexture.width, (uint)cam.targetTexture.height);

        string photoTime = GetTimeStamp("");
       
        print("SceneName: " + sceneName);

        if (Directory.Exists(Application.persistentDataPath))
        {
            print("Capture Path: " + Application.persistentDataPath);
            NativeGallery.Permission permission = NativeGallery.SaveImageToGallery(Im, "gameName", sceneName + "_" + photoTime + "_ - n" + FileCounter + ".png");
            File.WriteAllBytes(Application.persistentDataPath + "\\" + sceneName + "_" + photoTime + "_-n" + FileCounter + ".png", Bytes);
            FileCounter++;
        }       
        cameraFlash.SetActive(false);
        Destroy(Im);
    }

Have you managed to find a fix for this?

In my case I solved it by using OpenGLES3 instead of Vulkan

2021.3.9f1 LTS version is problematic at render texture in android build. I tried a lot of things but then I switched old version unity LTS 2020. It works fine for me now. Do not waste your time :confused: If you have a problem.

This is a bug in Vulkan in 2021, I’ve sent a bug report which the QA team confirmed, but the issue tracker link they provided is broken for weeks. Wouldn’t expect anything less.The problem lies in reading pixels from CPU → GPU

Same problem here. Just disabled Autographics API and set OpenGL as first option. Thanks guys, lost a entire day trying other solutions.

Hi, does anyone know if by any chance this Vulkan issue has been fixed in recent 2021 LTS versions?

Yes, I think its fixed in 2021.3.12. Some more info in my post here: