prefrontalcortex / UnityGLTF

Runtime GLTF Loader for Unity3D
MIT License
163 stars 41 forks source link

Ensure normal maps are exported as linear encoded .png textures #74

Closed robertlong closed 1 year ago

robertlong commented 1 year ago

When I was working on some exporter features I kept noticing that reflections didn't look quite right on assets exported with UnityGLTF. It turns out UnityGLTF was converting normal maps to sRGB. Also normal maps are data textures and should generally be exported with lossless formats so I made them export as .png now.

You can see the issues with the following test asset: https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/NormalTangentMirrorTest

hybridherbst commented 1 year ago

Hey, is your Unity project in Linear or Gamma colorspace? Also, are you on Mac by any chance?

I believe originally UnityGltf supported Gamma but I haven't tested that extensively. Linear should be 100% working, also with normals, without any wrong conversion (pretty strictly verified on Windows and Android, not sure about Mac). Unfortunately that code path you made changes in needs to be extensively tested across multiple supported platforms as there's a bunch of rendering differences / Unity bugs in that (thus the weird GL.sRGBWrite which should absolutely not be required).

Regarding compression, in the export settings, which you can also pass into any export programmatically, you can specify default compression settings - e.g. you can set that to 100% JPEG. The distinction is that textures that need an alpha channel are exported as PNG and textures that don't (like normals) are exported as JPEG (with adjustable quality).

I'll try to reproduce with that model!

robertlong commented 1 year ago

I'm on Mac and I'm always using Linear. I'm not sure the change toGL.sRGBWrite = false; is required. I can test on my end. I can also use JPEG if you'd rather not make that change.

I believe the important bit is RenderTextureReadWrite.Linear. Otherwise my normal maps look washed out and in-engine they don't handle reflections correctly.

hybridherbst commented 1 year ago

Thanks for confirming – the annoying thing is that combinations of Unity version + platform + render pipeline + current build target behave slightly different. Sorry for not catching that Mac is now broken... I do have Unit tests in a separate repo but they run on Windows only right now.

hybridherbst commented 1 year ago

Unit tests on Windows look good, let's roll with this and see if other issues arise

hybridherbst commented 1 year ago

I did roll back the PNG export change:

I assume you're running files through the pipeline anyways? In which case I think either of the above should work (e.g. we're using the heuristic and 100% JPEG for Needle Engine)

robertlong commented 1 year ago

Yeah the 100% JPEG trick will work just fine.