1
\$\begingroup\$

enter image description hereI'm working on a character generator that creates thumbnail sprites for each character. I'm using a separate camera that renders to a RenderTexture, which is used to create a sprite using ReadPixels(). The resulting sprites appear to have their colors multiplied. I'm stumped. I've messed around extensively with lighting and ambient lighting. Right now the only lighting is ambient. I've tried various color formats for the RenderTexture. I've tried assigning different materials to the resulting sprite, including the default.

Here is the relevant code, which generates the sprite:

IEnumerator GeneratePortrait(Npc npc)
    {
        Texture2D tex = new Texture2D(512, 512);
        RenderTexture.active = rt; //assigned at Start()
        tex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
        yield return null;
        tex.Apply();
        RenderTexture.active = null;
        npc.sprite = Sprite.Create(tex, new Rect(0, 0, 512, 512), new Vector2(256, 256));
    }

Update I tried changing the line that creates the texture to Texture2D tex = new Texture2D(512, 512, TextureFormat.ARGB4444, false); This shouldn't work; the format of the RenderTexture is the default for the target platform R8G8B8A8_UNORM but the result is much better. Still some multiplication happening, but acceptably close.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ This looks to me like it could be a difference in gamma correction. You may want to see if you're saving the texture in linear RGB then reading it as sRGB or vice versa. \$\endgroup\$
    – DMGregory
    Sep 3 at 19:07
  • 1
    \$\begingroup\$ Thanks as always DMGregory, although I'm not sure I follow, or at least understand how to apply your suggestion. The texture and sprite are created on the fly; the texture is applied to the sprite immediately (not saved and then read back in). I did try switching the project's color space from linear to gamma, which did make a perceptible difference, but that's not really a practical solution as it affects many other things... docs.unity3d.com/Manual/… \$\endgroup\$ Sep 3 at 19:57
  • 1
    \$\begingroup\$ Did you try passing linear = true in your Texture2D constructor? \$\endgroup\$
    – DMGregory
    Sep 3 at 22:36
  • 1
    \$\begingroup\$ Actually I overlooked that parameter completely! Thank you for pointing that out. I tried it with the old code and it does improve things but colors are still a little off/ dark. \$\endgroup\$ Sep 3 at 23:15

1 Answer 1

2
\$\begingroup\$

Use Graphics.CopyTexture() instead of ReadPixels()

CopyTexture Docs

Not sure why ReadPixels is doing the weird stuff, but CopyTexture doesn't. Here's the updated code:

IEnumerator GeneratePortrait(Npc npc)
    {
        Texture2D tex = new Texture2D(512, 512,TextureFormat.RGBA32, 1, false); // need to specify only 1 mipmap level
        RenderTexture.active = rt;
        Graphics.CopyTexture(rt, tex);
        yield return null;
        RenderTexture.active = null;
        npc.sprite = Sprite.Create(tex, new Rect(0, 0, 512, 512), new Vector2(256, 256));
    }
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .