Feedback Wanted: Global Texture Import Size/Compression Overrides

Hi! So, importing textures often takes “forever” in a decent size project. We’ve been spending some time doing general optimizations for texture imports in 2021.x versions (see this thread ), but here’s another idea that would be good to get feedback on.

My theory is that there are cases during production, where it’s basically “I don’t care if textures look slightly wrong or don’t match the final look”. If someone is a programmer investigating some physics bug, or an audio designer, or someone working on character controller, they probably don’t care about exact look of the textures.

Question: What if there was some easy way to globally (per-user, not affecting version-controlled import settings) to reduce imported texture resolution and/or turn off lengthy texture compression?

A hypothetical place where this could be placed is, say, within the Build Settings window itself. Like this:


by default it would not change any behavior, but within the overrides you can pick, for example:
6729232--774523--texture-overrides-maxsize.png
6729232--774526--texture-overrides-compression.png

Some of this is somewhat similar to already existing “Compress Assets on Import” editor preference, that basically does the same as “Force Uncompressed” above (i.e. skips texture compression).

The “Force Fast Compressor” above is where textures are still compressed (so they take the same amount of memory, load time, GPU performance), but sets the compressor itself to use “fast” compression mode, where it spends less effort trying to compress the texture. For some formats (ASTC, BC7 etc.) it’s 5x-10x faster at doing the compression, at some expense of image quality.

So the questions are:

1. Does the above sound like a useful thing to have?
2. Is Build Settings a good place where to put these settings in?
3. Something else I haven’t thought about?

7 Likes
  1. Yes useful to have!
  2. Yes or project settings
  3. Extra option - Only compress textures used in build ( not all in project folder )

I would use the faster way during development and only compress at full slow speed quality when starting the optimization phase.

3 Likes

Yes. Uncompressed but half res would be useful too (I guess uncompressed and something like max 512 is fine). The use case is “I just want to make a build NOW to check something unrelated / I need to show something at a presentation, and half of my textures aren’t compressed yet”. It happens surprisingly often.

A Warning in the console when you’re building with those overrides would be also prudent, since you also probably don’t want to release something with these settings.

(and / or make sure we can turn this off by code so when we click our “Prepare for final build” button we can make sure these are turned off)

Yes.

Another dropdown where I can override the compression format for iOS (like you can for Android).

2 Likes

Currently in quality settings there is also the option the half the texture resolution, just to keep in mind that it may be better to have all in one place.

Perhaps a new quality setting for fast exports?

1 Like

I like the “force fast compressor” option idea, as it only effects quality. The problem with setting a max texture size it is may kill LUT tables, and break all kinds of things that use them and expect them to contain exactly sized data. (This is, btw, one of my main issues with all of unity’s texture scale settings, and why I never use them - there are issues with MicroSplat that happen if the user sets the project to half res textures and try’s to pack the texture array- it ends up having one less mip with white in the last mip map). Could a texture have an “do not resize” flag? That would fix that issue both here and for my current use cases as well.

Ideally Unity would be able to do things like this in sweeps on a background thread- so bring in all textures as fast as possible as a first pass, then go up a mip or two and do a second pass. The real problem here is the blocking nature of the editor, if this was fixed I wouldn’t care if all textures were standard checkerboard patterns until compression was done, but I realize that’s a larger task. But it is the right one to solve.

9 Likes

I believe the one in Quality setting still adds the full res texture in the build (and ram at runtime), but forces everything to ignore LOD0 and start at LOD1. (unless something changed)

Yes good good points Jason!
The blocking is what stops us from doing any work during the compression stage.

@AcidArrow Thanks I did not know that

As an example lets say I have a project with 100 GB uncompressed textures coming from various assets packs in order to kitbash together a prototype.

Lets say I made a scene that uses 1 GB of textures coming from these packs.

I set compression at import to none.

What is taking the most time:

  1. compressing 100 GB of textures to a format that I will not use in the final
    build ( because default texture compression settings )

  2. Manually setting the right compression format for each texture

3 Blocking the editor during compression

4 Finding that one texture that is set at 8k exr and eating up all the storage in the build.

@Peter77 Had a nice tool for 2 and 4, texture overview. I wish Unity would make a texture overview tool native so we can easy change many texture settings at once and easy sort by properties.

1 Like

+All the textures from demo scenes in downloaded assets that I have spent so much time compressing over the years and they have never made it in a build.

I do think this is an Asset Database feature/issue though, which is probably outside of the scope of what Aras is doing (and it’s a bummer that we semi-recently had Asset Database v2 introduced, and really not that much has changed? all the issues and quirks are still there).

1 Like

My main problem with texture compression is that it blocks the entire editor like Jason said. If it could be done in an asynchronous way that alone could be a massive workflow improvement for me.

I think if you guys had some sort of texture group settings similar to what Unreal has where you can specify global settings for the textures in that group would give us a little more control. Plus you could also do what you are proposing with the global settings you mentioned.

For example, if I wanted to set a certain texture mipmap bias I currently have to write an asset importer and somehow identify the specific textures I want to modify whereas if I have a centralized location to specify a configuration for a group of textures kinda solves the problem neatly.

2 Likes

Actually just the copy into the library folder is enough to make this time consuming.

Having worked on projects with 18 hour import times (on a meticulously clean data tree, mind you), and contracted with companies with 8-12 hour import times, I can honestly say that in my opinion making this not a blocking operation is the #1 quality of life improvement that could be made to Unity. I hate having to charge someone a day’s work because my computer is just sitting there importing a project filled will assets that they aren’t even using, and I hate even more trying to convince the team that it’s worth their time to clean up their project instead of focusing on whatever they are trying to get done. (Though to be honest I’d still be doing that if texture import times were not an issue).

3 Likes

In theory one day some combination of UAS rule changes and the package manager would allow us to move those outside of the main packages, making them optional, which would be nice to decrease this burden.

To be fair, this is because mipMapBias is not exposed on the Texture Import settings, which just seems like a funny oversight.

But yes, Unity’s texture importing/scaling stuff is anemic for most real world cases, as it will destroy LUTs and lacks any kind of fine detailed control. So no real project I’ve worked on has ever used it, and I think a lot of the hobby developers just use it because they don’t understand performance and think they should half the texture res of everything “to increase framerate”. It basically treats mobile as if we’re all on iPhone 1’s or 2’s, not the wide ranging ecosystem it is today.

So what happens to a 2048 texture which is set to max1024 with these new settings, and half res textures in the quality settings? Does it compress a 1024 version then drop the highest mip for rendering? What does its .mipMapCount and width/height return? I do a lot of texture packing in MicroSplat, and the texture size settings are on my configs, so it would scale the input to 2048 and output a texture array at that size (in a scriptable object, mind you, not the new texture array stuff added to 2021). Ideally, I’d prefer if my editor code could work with the original, uncompressed texture data, not from the data in the library folder. Then I would be unaffected by any of these settings, which can already cause issues that are hard for users to reason about.

1 Like

True enough but that detail has always bugged me so much and complicated things more than it should have.

Thanks for feedback so far! Answering all of them in one go:

and

These are being considered/designed by other folks as we speak, i.e. ability to set import settings not for each& every individual asset, but based on some “rules” (paths, folders, packages etc.). But that’s a much larger/longer thing.

and

That one is also being worked on by other folks, i.e. both ability to import things “on demand” and “in the background”, and also to import more than one asset in parallel, etc. But again, much larger/longer thing.

This one is only a runtime setting, that does not affect import at all, and (mostly) does not affect the build (not 100% – if all the quality settings that are included into the build say “half resolution textures”, then it can drop the largest mip level).

Yeah. Good question is, where/how would that be specified. Easiest one is adding some optional command line parameters that one can pass. Besides that… where these would be set? Somehow in the Hub UI?

Yes.

From what I remember, it was because some platforms (IIRC OpenGL ES and Metal) don’t have such a concept in the sampler state. But my memory is fuzzy on this.

Exactly the same as if you’d manually set it to max 1024 in the import setting today. In the build it would be 1024, then quality setting would make the largest mip be dropped at load time, so effectively it would become 512. Yes that’s confusing to some extent, but is it more confusing than today? I mean today you have exact same thing with texture import max size setting & the runtime quality setting for “drop some mips”, right?

In any case – if we had things like “import assets in the background” and/or “compress textures in the background”, and/or “configurable import settings that are easier to setup across whole project than setting them for each asset”, and/or “configurable build variants with setting overrides” or somesuch, then the above would most certainly not be needed. Most of what I mentioned here are being investigated or worked on by some folks at Unity, but all of these are “long projects”. Whereas the above suggestion I literally have working on my computer today. So the question is, does it make sense to have this small improvement, that likely will get obsoleted in Some Years by better systems.

3 Likes

This drop down has plenty of space, but it could also be part of Advanced Project Settings?

6729667--774562--Screenshot 2021-01-15 at 10.19.24 PM.png

Also this is slightly off topic, but the “Compress Assets on Import” preference should be changeable from the hub as well, since if it’s On, I either have to suffer the whole project compressing, or I have to create a new dummy project (or have one around), go to preferences, close that, open the project I actually want.

1 Like

Yes it is a welcome option!

I haven’t tried on Metal, but bias definitely works on GL ES 2.0 and above (not sure about 1.0, and I’m fairly sure it works on metal, but I haven’t actually tried it). Also… maybe on platforms that the settings does nothing, then it does nothing, not sure why that prevents something from being in the importer :slight_smile:

A “nice to have” feature would be if using Force Uncompressed would use a dynamically calculated per texture max size to prevent exceeding the memory usage of the intended compressed settings for that texture. So, for example, a 512x512 DXT5 or ASTC 4x4 would end up as a 256x256 RGBA32, 512x512 DXT1 or (RGB) ASTC 6x6 would be a 128x128 RGB24. Not perfectly like for like, but on memory constrained platforms or projects pushing limits, this would be exceedingly more useful than global clamps. Especially since it wouldn’t impact any already uncompressed textures. Those generally don’t require significant import times (ignoring convolved cube maps, which maybe need a separate option?).

1 Like

I guess my vote then would be to add the texture compression quality option and not the max size option, if anything at all. I guess it depends on the timeline; I hate putting in stuff that’s just going to go away, because I’m always working across 2-3 years of unity versions, and then you end up with tons of #if UNITY_X all over the place to handle stuff.

1 Like

It would be nice to have some way to set this as a profile. One thing that’s important for me is to make it easy to kick out a build with production settings, and not have to re-make the build because you forgot you had the wrong texture settings.

This might be a larger change, though. It’d just be nice to be able to define a build profile that had arbitrary modifications to Project Settings. :slight_smile:

  • Debug (Mono-512textures)
  • Production (IL2CPP-maxcompression)
1 Like