Forum rules - please read before posting.

[Camera: crossfade] not working correctly in linear space.

The Texture2D created in "MainCamera.cs" for the Crossfade Action does not bypass the sRGB sampling; so it doen't look right in linear space.

The fix for this is very simple, you just have to set the bool "linear" of the texture to true. In the line 793 of MainCamera.cs change from
crossfadeTexture = new Texture2D (Screen.width, Screen.height, 0, 0, false)
to
crossfadeTexture = new Texture2D (Screen.width, Screen.height, 0, 0, false, true)

I thought I should share this information in case someone finds it useful. Aaand sorry for my english!
«1

Comments

  • Thank you!  I would like to add this in officially - do you know if this change will affect the look in non-linear space?
  • It should not. I tested it and i'm certain it doesn't. However I'm not 100% sure if that is the case for platforms that don't support linear color space. If you want to make sure no problem will happen, you can check the color space the unity player is in with "QualitySettings.activeColorSpace == ColorSpace.Linear" and create the texture accordingly.
  • Good suggestion - look out a correction in v1.55.
  • Sorry for digging up an old corpse, but I just switched my project over to Linear space and now I get a bright flash whenever I do a Crossfade Action. Are there other settings that need to be adjusted for this to work? I'm on Unity 2018.3 and latest AC.

  • The latest AC does account for the active colour space when creating a crossfade texture. What colour space are you working in?

  • I changed my project to Linear Space. I realised I'm on AC 1.68.1, has there been any changes regarding this in the latest update?

  • No, none. I shall attempt a recreation.

  • So far as I can tell, this is an issue with Unity. The screenshot texture is linear, and there are threads on the Unity forums about issues with screenshots in linear space. None that I've found reveal a solution, unfortunately.

  • Ah, thanks. Always worrying when Unity itself is the culprit, they don't have the best reputation for fixing old issues.

  • I've found a workaround for this issue, I loop through the screentexture's pixels and set them to linear. This makes the white flash disappear when crossfading from one scene to the next!

    private IEnumerator ExitSceneWithOverlay ()
    {
    yield return new WaitForEndOfFrame ();
    Texture2D screenTex = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
    screenTex.ReadPixels (new Rect (0f, 0f, Screen.width, Screen.height), 0, 0, false);
    for (int y = 0; y < screenTex.height; y++)
    {
    for (int x = 0; x < screenTex.width; x++)
    {
    Color color = screenTex.GetPixel(x, y);
    screenTex.SetPixel(x, y, color.linear);
    }
    }
    screenTex.Apply ();
    SetFadeTexture (screenTex);
    KickStarter.sceneChanger.SetTransitionTexture (screenTex);
    FadeOut (0f);
    }

  • Nice work! Permission to integrate into AC proper?

  • Of course! Maybe this should be wrapped in a linear space check, I don't think it's needed if you work in gamma space.

  • Yes, indeed - however, it seems to only work on my end when replacing "color.linear" with "color.gamma" - even in linear space.

    This may be platform-dependent. So far I've tested with a Mac - are you using a PC?

  • Yes, I'm on PC, building for Switch at the moment.

  • I just noticed while the crossfade between scenes in linear space (on PC) works now, the crossfade between cameras still have the white flash issue. I've worked around it by adding the same code to the StartCrossfade function. This works for me, note I had to remove the true condition in the first colorspace check, but keeping it here to provide clarity:

    protected IEnumerator StartCrossfade (object[] parms)
        {
            float _transitionDuration = (float) parms[0];
            _Camera _linkedCamera = (_Camera) parms[1];
    
            yield return new WaitForEndOfFrame ();
    
            if (QualitySettings.activeColorSpace == ColorSpace.Linear)
            {
                crossfadeTexture = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
            }
            else
            {
                crossfadeTexture = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
            }
            crossfadeTexture.ReadPixels (new Rect (0f, 0f, Screen.width, Screen.height), 0, 0, false);
            if (QualitySettings.activeColorSpace == ColorSpace.Linear)
            {
                int _width = crossfadeTexture.width;
                int _height = crossfadeTexture.height;
    
                for (int y = 0; y < _height; y++)
                {
                    for (int x = 0; x < _width; x++)
                    {
                        Color color = crossfadeTexture.GetPixel(x, y);
    #if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
                                            crossfadeTexture.SetPixel (x, y, color.gamma);
    #else
                        crossfadeTexture.SetPixel(x, y, color.linear);
                    #endif
                                        }
                                    }
                                }
            crossfadeTexture.Apply ();
    
            ResetMoving ();
            isCrossfading = true;
            SetGameCamera (_linkedCamera);
            FadeOut (0f);
            FadeIn (_transitionDuration);
        }
    
  • Thanks, I'll attempt a recreation.

  • Sorry for returning to this issue, but it cropped up again now while upgrading the project to 2018.4.12f1 on PC. Maybe Unity did some changes to this, as when building to PC I had to remove the looping through pixels and setting them to their correct color space. This also had some performance issues when running on Switch, so perhaps the original code you had here was best.

  • What's the appearance when reverting to the original code? Does 2018.4 cause it to display correctly?

    It may be that Unity have fixed an error here, because AC's original code sets the Texture's "linear" property according to the active colour space - which I'd have thought would be enough.

  • On PC, it seems to be displaying correctly on 2018.4 with the original (pre-looping over pixels) version. So I would suggest removing this code in the next version of AC, or putting them in a Unity 2017 check. Unfortunately there seems to be some issues still when building to Switch, but I'll have to investigate more. But the pixel loop is very slow, almost unusable anyway, so in my opinion this hack I made did not work out :)

  • I just upgraded to 1.70, and that pesky white flash has returned on 2018.4 on Windows. I don't understand why, but in MainCamera.cs when changing

    Texture2D screenTex = new Texture2D ( ACScreen.width, ACScreen.height, TextureFormat.RGB24, false, (QualitySettings.activeColorSpace == ColorSpace.Linear));

    to

    Texture2D screenTex = new Texture2D ( ACScreen.width, ACScreen.height, TextureFormat.RGB24, false, false);

    it works again with no white flash. Counter-intuitive, not sure if this is a Unity bug or not.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.