atteneder / glTFast

Efficient glTF 3D import / export package for Unity
Other
1.24k stars 250 forks source link

Editor-imported `.glb` assets with textures use wrong texture format on Android, resulting in high memory usage #552

Open hybridherbst opened 1 year ago

hybridherbst commented 1 year ago

Describe the bug Seems that when importing a .glb file at editor time, the textures are imported as DXT1 (on Windows at least). When building to Android, it looks like they stay DXT1 and get unpacked as bitmaps at runtime, resulting in giant memory usage. This is a blocker for using glTF as a regular editor-usage format.

Expected would be: when building to Android (and probably other platforms), textures are reimported with the correct platform settings.

To Reproduce Steps to reproduce the behavior:

  1. Import a glb file with embedded textures in the editor
  2. Note textures are DXT1 (on Windows at least)
  3. Build to Android
  4. Note high memory usage (crashes with large files)
  5. Import the same thing as glTF with separate textures
  6. Build to Android
  7. Note expected memory usage (no crash with large files)

Desktop (please complete the following information):

additionally (if significant for the bug):

Additional context Regular textures allow per-platform compression settings, not sure how to achieve that for a custom importer: image ``


Some more data – reproduction files: Textures-4k.zip

Imported as Textures-4k.etc1s.glb
Textures are 4x larger than they should be
image

Imported as Textures-4k.gltf with textures set to ASTC_4x4 for Android in Unity
This is what I would have expected
image

Imported as Textures-4k.glb
Still ends up too large, seems textures are not compressed at all at build time
image

Imported with Unity's default settings (ASTC_6x6, not available in KTX2 if I'm not mistaken)
image

So with the glb file with compressed textures it ends up at 4x the memory usage of "regular" Unity imports...


GPU size according to https://gltf.report (not necessarily accurate depending on platform, but good ballpark estimate)

Textures-4k.glb:
image

Textures-4k.etc1s.glb
image

Also worth noting: the estimated GPU size in gltf.report is pretty exactly 50% of Unity's number for ASTC4x4; seems in Unity it always ends up as RGBA while the textures actually don't have an alpha channel. I can open a separate bug report for this if needed.

atteneder commented 1 year ago

@hybridherbst Thanks a lot for bringing it up! I'll spend some more thoughts on it soon.

Possibly relevant:

https://docs.unity3d.com/2023.1/Documentation/ScriptReference/AssetImporters.AssetImportContext-selectedBuildTarget.html

hybridherbst commented 1 year ago

Thanks!

I'm wondering if in-editor KTX2 imports should maybe always be imported as RGBA32 and then compressed with Unity's built-in compression methods per-platform.

atteneder commented 1 year ago

Absolutely! Ideally there would be a way to re-use large portions of the default Texture(2D)ImportSettings inspector.

On top of that (RGBA32 by default) a "do not re-encode" option would make sense in case the KTX already contains the desired format.

hybridherbst commented 1 year ago

@atteneder any news on this? :)

atteneder commented 1 month ago

I've dabbled with it today. Turns out you can re-encode textures much like a regular textureimporter does via TextureGenerator.GenerateTexture (e.g. the 4k textures are automatically downsized to 2k by 2k and encoded to DXT1 on my machine). What's still missing in my PoC is that the texture assignments are broken and there's no UI to actually change texture import settings.

KTX is another beast...it would need the exact same modifications to its importer plus an API that accepts TextureImporterSettings/TextureImporterPlatformSettings.

I don't have time currently to proceed with it, unfortunately.