zeux / meshoptimizer

Mesh optimization library that makes meshes smaller and faster to render
MIT License
5.6k stars 480 forks source link

[Feature Request] Ability to selectively compress textures by texture name? #438

Closed ROBYER1 closed 2 years ago

ROBYER1 commented 2 years ago

We are noticing the compression of normal maps in the GLTFPacked models is not ideal for some use-cases and I am currently trying to find a good workaround for this but is it possible for there to be a way to limit what textures are compressed in the file by their texture names or something? Ie. compress all textures except ExampleNormalMap.jpg

zeux commented 2 years ago

gltfpack supports per-class compression specification, this might be sufficient:

gltfpack -tc -i in.gltf -o out.gltf # compresses all textures using ETC1s
gltfpack -tc -tu normal -i in.gltf -o out.gltf # compresses all textures using ETC1s except for normal maps that use UASTC

I thought -tc also supports mask specification so that you can eg say gltfpack -tc color -i in.gltf -o out.gltf to only compress color textures and leave the normal map alone but it looks like this doesn't work yet, I'll need to implement this.

ROBYER1 commented 2 years ago

gltfpack supports per-class compression specification, this might be sufficient:

gltfpack -tc -i in.gltf -o out.gltf # compresses all textures using ETC1s
gltfpack -tc -tu normal -i in.gltf -o out.gltf # compresses all textures using ETC1s except for normal maps that use UASTC

I thought -tc also supports mask specification so that you can eg say gltfpack -tc color -i in.gltf -o out.gltf to only compress color textures and leave the normal map alone but it looks like this doesn't work yet, I'll need to implement this.

Thanks the addition of the -tc command with masks working properly would be great. I tried the gltfpack -tc -tu normal -i in.gltf -o out.gltf command on a GLTF where I wanted to keep the Normal map as a 900kb Jpeg file in the GLTF, unfortunately it still converted the Jpeg of the normal map to a KTX2 file which was 3.8mb instead of the original size.

What would you suggest to do in this scenario? We are using GLTFPack to compress our files as small as possible without perceivable quality loss.

I do have a workaround workflow using PVRTextool manually ourselves to export the Albedo + Metallic textures as supercompressed .KTX2 files, then exporting the Normal map as a .Jpeg compressed as small as possible, then editing the GLTF file Images list to change the texture formats manually before using GLTFPack without the -tc command as we have already sorted the textures. That still gives me the smallest possible file size at adequate quality.

zeux commented 2 years ago

Ah, right, I missed that the source texture is JPEG - in that case yeah UASTC would be significantly larger. I think this simply needs an improved -tc command, I'll implement this soon.

zeux commented 2 years ago

You can grab the binaries with the PR above from this job's artifacts to validate that this works as expected: https://github.com/zeux/meshoptimizer/actions/runs/2716336752

Using gltfpack -tc color,attrib -i input.gltf -o output.gltf should now leave the normal maps uncompressed.

ROBYER1 commented 2 years ago

You can grab the binaries with the PR above from this job's artifacts to validate that this works as expected: https://github.com/zeux/meshoptimizer/actions/runs/2716336752

Using gltfpack -tc color,attrib -i input.gltf -o output.gltf should now leave the normal maps uncompressed.

Tried with that exact command and using the windows copy from the artifacts of the link but I get this error? Expected option, got color attrib instead

Seems the provided options arguments don't read and I'm not sure - this is the exact artifact build I tested with - https://github.com/zeux/meshoptimizer/suites/7471540762/artifacts/306186368

zeux commented 2 years ago

I just tried the same command with the same artifact and it did work; the error message you're getting is a little odd, I wonder if there's some shell expansion going on...

Here's the precise command I ran (from cmd.exe): C:\test> gltfpack.exe -tc color,attrib -i data\test\scene.gltf -o test.glb

ROBYER1 commented 2 years ago

I just tried the same command with the same artifact and it did work; the error message you're getting is a little odd, I wonder if there's some shell expansion going on...

Here's the precise command I ran (from cmd.exe): C:\test> gltfpack.exe -tc color,attrib -i data\test\scene.gltf -o test.glb

You're right, the Powershell was doing some expansion and using the last or nearest available gltfpack.exe in the parent directory or subfolder - I noticed this as without appending .\ before the command in Powershell, it will fall back to using the last valid gltfpack.exe.

I just tried copying my test folder with the exact artifact .exe I wanted to use to another laptop that had never seen gltfpack.exe before and it worked just fine so i can confirm your PR worked and is perfect thanks!

I will make sure to explain to our 3D team that they should remove any previous gltfpack.exe's they have in the subfolders or parent folders if they use the new one and I will also check if the .\ before the command will at least enforce using the gltfpack.exe in the current folder when I'm back at my work laptop. Thanks again for your help with this and for the speedy PR, it's a huge help having these extra parameters to change when converting files!

ROBYER1 commented 2 years ago

@zeux Just out of curiosity, is there an option via command to set the Quantization/compression of the normal map to be higher than that of the other textures? I'd like to try that also, thanks

zeux commented 2 years ago

Yes, you can control texture quality via -tq parameter, and it also supports masks - see command line help.

Note that when using ETC1S (-tc), the encoding is just not strong enough for normal maps. The quality defaults to 8 but setting it to 10 (max) isn't going to make it much better. When using UASTC (-tu), it's possible to go much lower and reduce the size impact, e.g. a possibly reasonable configuration is -tc -tu normal -tq 3 normal (sets ETC1 compression for all textures, then overrides normal maps to use UASTC with quality 3). That said, it's still going to be noticeably larger than JPEG.