Skip to content

Conversation

mtschoen-unity
Copy link
Collaborator

Purpose of this PR

Add a utility window for finding textures which are only a single solid color.

Testing status

Tested while doing Quest optimization

Technical risk

Low -- adds functionality

Comments to reviewers

This was kind of a fun one! I often find myself in an optimization loop, identifying large textures in builds and trying to figure out which ones can be shrunk and by how much. Whenever I come across a solid color, I think:

  • Score! We can squish this down to 32x32!
  • Hm... am I sure this is a solid color, and not some subtle gradient or something?

It comes up often enough that I decided to build a tool! The Solid Color Texture window scans the project for solid color textures, lists them for you just like Missing Project References along with a list of unique colors with the textures grouped by color. It also includes a handy button to apply import settings to shrink the texture down to 32x32.

I still need to update the readme but I'll probably include the following image:
image

There are one or two future improvements to be made

  • As a fallback for non-readable texture, I used AssetPreview.GetAssetPreview to get a readable texture. Unfortunately, this texture will be 128x128 at a maximum, so it's possible that we would count a subtle enough texture as a solid color. It's a nice optimization, though
  • The way the UI lists assets in a folder structure is cribbed from Missing Project References. They could probably share code.
  • It might be a good idea to do the AssetDatabase work as a coroutine to avoid locking up the UI for that portion of the scan. It seems to be relatively quick, though, even for the ~800 textures I was testing it on.

There's a cool trick that I use here which I'll try to call out in the readme as well. The Color32ToInt class gives us a "free" conversion from Color32 to int. The only performance cost of the conversion is writing to a struct field, which is very fast. This makes it much faster to compare two colors, which we do a lot here. I'm not sure why Color32 doesn't just expose this int value because it does the same thing internally, but doesn't provide an equality comparer. Just that class on its own is a pretty powerful lesson to share in this repo.

In case it's not clear what's going on from the comments and context: we define a struct which has two fields of a different type in the same location. Thus, setting either of these fields will write to the same memory location, so it will in practice "overwrite" the other field. If you write to the int field, you can read that value back as a Color32, splitting the int into the 4 'byte' values. Conversely, if you write to the Color32 field, you can read back a single int which is equivalent to the 4 bytes concatenated together. You can do this for arrays, too. So if I wanted to just get the result of GetPixels32 as an int[], I could use a similar class with an int[] field and a Color32[] field which both have the FieldOffset(0) attribute. Note that you can't do this with Color, as it uses 4 floats which are 32 bits each.

…gProjectReferences;

Add Shrink/Shrink All buttons;
Add unique color list
Add line separators and beautify UI;
Split Color32ToInt into its own file
@AndrewTHEManeri
Copy link
Collaborator

Does this scan the alpha channel? For example - the wedge texture it is picking up as solid but there is definitely variation in the alpha.

@mtschoen-unity
Copy link
Collaborator Author

Yep! All 4 colors get squished together into an int, and if the two ints for all the pixels don't match exactly, we don't count it as a solid color. The only way a texture could slip through is if it perfectly downsamples to a solid color at 128x128.

@mtschoen-unity mtschoen-unity mentioned this pull request May 31, 2022
@mtschoen-unity mtschoen-unity merged commit 60b6d70 into main May 31, 2022
@mtschoen-unity mtschoen-unity deleted the solid-color-textures branch May 31, 2022 19:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants