Importing EXR textures as linear not working.

I am trying to import a 32bit float linear open exr texture “depth map” that I have pre rendered with another software, but unity wont import it correctly, when I disable the sRGB import nothing happens it still importing as sRGB, also is it possible to import it as RFloat? I can’t find it in the import options, but says it exist in the documentation.

I am using unity 2019.2.8f1

Most of these properties are not visible, how do I find them?

The open EXR file I am using :
http://www.patan77.com/download/pillars_01_zdepth.exr

I’m having similar problems, Unity 2019.2.2

It seems that the importer for EXR with RGFloat and RGHalf is fundamentally broken (!) and corrupts incoming images.

There appears to be NO manual override for either format, and the “Automatic” setting is simply randomly broken. It consistently corrupts images with certain ranges, and consistently does NOT corrupt images with other ranges.

Yep, confirmed. It’s a (huge, enormous) bug in Unity 2019.

Switching the project from Gamma to Linear - which according to the manual will have no effect if that sRGB box is unchecked - immediatley re-colors the textures.

So the checkbox is broken in 2019.2, and Gamma space projects are not supported / cannot be used (Unity will corrupt the incoming textures)

Hello, if you haven’t done so, please submit a bug report so that we can investigate this further - the steps to do so are detailed here: https://unity3d.com/unity/qa/bug-reporting?_ga=2.238855360.1506675044.1572805904-1364330384.1571764025

Thanks!

Yep, back in November I submitted two bugs on this topic with tiny projects demonstrating the problems. I wasn’t 100% sure what was going on, so my bug description could be improved, but I figured I could explain better / discuss with a Unity tech when someone replied to the bug-report.

I don’t know what the wait-time is at the moment, but it’s been almost 4 weeks and I haven’t received a reply from Unity yet (I got the standard confirmation that a bug report had been received). Maybe it’s being fixed/worked on, and I’ll get a happy automatic email next month saying it’s fixed :).

Same here. Importing pre-rendered depth maps as RFloat and the values get changed by the importer.

In version 2019.3 this was fixed, in version 2021 the same problem is again. This is the only way to work with HDR textures (for example with vertex to animation texture) and the unity developers breaks it all the time!
it’s so hard to test everything you change.

1 Like

We’re seeing the same problem. There is no way to change the import settings to correctly import a half-float EXR texture.

I could not find a fixes, so I made a custom texture importer using zip. (Zip files should be included to “StreamingAssets” folder for including to a build)
Maybe it will be helpfull.

public static async Task<Texture2D> ReadTextureFromFileAsync(string pathToFileWithoutExtension, bool linear = true, FilterMode filterMode = FilterMode.Bilinear, TextureWrapMode wrapMode = TextureWrapMode.Repeat)
    {
        Texture2D tex;

        if (!File.Exists(pathToFileWithoutExtension + ".gz"))
        {
            Debug.LogError("Can't find the file: " + pathToFileWithoutExtension);
            return null;
        }
        try
        {
            using (var fileStream = File.Open(pathToFileWithoutExtension + ".gz", FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (GZipStream gzip = new GZipStream(fileStream, CompressionMode.Decompress))
                {
                    using (MemoryStream stream = new MemoryStream())
                    {
                        await gzip.CopyToAsync(stream);

                        var rawTextureDataWithInfo = new byte[stream.Length];
                        stream.Seek(0, SeekOrigin.Begin);
                        await stream.ReadAsync(rawTextureDataWithInfo, 0, rawTextureDataWithInfo.Length);
                        {
                            var format = (TextureFormat)BitConverter.ToInt32(rawTextureDataWithInfo, 0);
                            int width = BitConverter.ToInt32(rawTextureDataWithInfo, 4);
                            int height = BitConverter.ToInt32(rawTextureDataWithInfo, 8);

                            var rawTextureData = new byte[rawTextureDataWithInfo.Length - 12];
                            Array.Copy(rawTextureDataWithInfo, 12, rawTextureData, 0, rawTextureData.Length);

                            //var gFormat = GraphicsFormatUtility.GetGraphicsFormat(format, false);
                            tex = new Texture2D(width, height, format, false, true);

                            tex.filterMode = filterMode;
                            tex.wrapMode = wrapMode;
                            tex.LoadRawTextureData(rawTextureData);
                            tex.Apply();
                        }
                    }
                }
                fileStream.Close();
            }
            return tex;
        }
        catch (Exception e)
        {
            Debug.LogError("ReadTextureFromFileAsync error: " + e.Message);
            return null;
        }
    }

    public static void SaveTextureToFile(this Texture2D tex, string pathToFileWithoutExtension)
    {
        var directory = Path.GetDirectoryName(pathToFileWithoutExtension);
        if (directory == null)
        {
            Debug.LogError("Can't find directory: " + pathToFileWithoutExtension);
            return;
        }
        if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);

        using (var fileToCompress = File.Create(pathToFileWithoutExtension + ".gz"))
        {
            int w = tex.width;
            int h = tex.height;
            var rawTextureData = tex.GetRawTextureData();
            var textureInfo = new List<byte>();

            textureInfo.AddRange(BitConverter.GetBytes((uint)tex.format));
            textureInfo.AddRange(BitConverter.GetBytes(w));
            textureInfo.AddRange(BitConverter.GetBytes(h));
            rawTextureData = Combine(textureInfo.ToArray(), rawTextureData);

            using (GZipStream compressionStream = new GZipStream(fileToCompress, CompressionMode.Compress))
            {
                compressionStream.Write(rawTextureData, 0, rawTextureData.Length);
            }

            fileToCompress.Close();
        }
    }

    public static void SaveRenderTextureToFile(this RenderTexture rt, string pathToFileWithoutExtension, TextureFormat targetFormat)
    {
#if UNITY_EDITOR
        if (rt == null) return;
        var currentRT = RenderTexture.active;
        RenderTexture.active = rt;

        var tex = new Texture2D(rt.width, rt.height, TextureFormat.RGBAFloat, false, true);
        tex.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
        tex.Apply();
        UnityEditor.EditorUtility.CompressTexture(tex, targetFormat, UnityEditor.TextureCompressionQuality.Best);
        tex.SaveTextureToFile(pathToFileWithoutExtension);
        RenderTexture.active = currentRT;
        SafeDestroy(tex);
        //SafeDestroy(tex2);
#endif
    }

Also it may help too
https://forum.unity.com/threads/floating-point-textures.821553

1 Like