Search Unity

Bug Render texture output color is different, more saturated.

Discussion in 'General Graphics' started by PHSenki, Mar 15, 2023.

  1. PHSenki

    PHSenki

    Joined:
    Feb 6, 2018
    Posts:
    13
    I tried using a render texture to capture a 3D object and display it as a sprite on the Canvas. It worked, but the colors are wrong, they turned out to be more saturated than the camera's output.

    Comparison Image:

    The three slimes on the back are 3D objects, the smaller one on the right is a sprite.



    Code (CSharp):
    1.  
    2.     public Sprite GetSprite()
    3.     {
    4.         Texture2D resultTexture = new Texture2D(resWidth, resHeight, TextureFormat.RGBA32, false);
    5.         snapCam.gameObject.SetActive(true);
    6.         if (snapCam.gameObject.activeInHierarchy)
    7.         {
    8.             Texture2D snapshot = new Texture2D(resWidth, resHeight, TextureFormat.RGBA32, false);
    9.             snapCam.Render();
    10.             RenderTexture.active = snapCam.targetTexture;
    11.             snapshot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
    12.             byte[] bytes = snapshot.EncodeToPNG();
    13.             Debug.Log("Snapshot taken!");
    14.             resultTexture.LoadImage(bytes);
    15.             resultTexture.name = "Texture From Shot ";
    16.         }
    17.         snapCam.gameObject.SetActive(false);
    18.         Sprite sprite = Sprite.Create(resultTexture, new Rect(0, 0, resultTexture.width, resultTexture.height), new Vector2(0.5f, 0.5f));
    19.         return sprite;
    20.     }
    21.        
    I tried changing the TextureFormat on the method that gets the sprite from the camera renderering texture and also on the rendering texture material.

    I tried putting the method in a coroutine and waiting until the end of the frame to make sure it would have renderered all lights.

    I suspect it could be the PNG encoding, but I have no idea. Can somebody share some light?
     

    Attached Files:

    Last edited: Mar 15, 2023
  2. restush96

    restush96

    Joined:
    May 28, 2019
    Posts:
    137
  3. lusuga

    lusuga

    Joined:
    Sep 29, 2020
    Posts:
    1
    i ran into the same problem, here is how i fixed it:


       for (int i = 0; i < desiredTextureToBeExported.width; i++)
    {
    for (int j = 0; j < desiredTextureToBeExported.height; j++)
    {
    Color color = desiredTextureToBeExported.GetPixel(i, j);
    color.r = Mathf.LinearToGammaSpace(color.r);
    color.g = Mathf.LinearToGammaSpace(color.g);
    color.b = Mathf.LinearToGammaSpace(color.b);
    desiredTextureToBeExported.SetPixel(i, j, color);
    }
    }
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    666
    There is also Color.gamma which does the same thing (as well as Color.linear for gamma-to-linear).

    Also, it might have been easier to render to a SRGB target in the first place by passing true as the last parameter to the Texture2D constructor.