supertuxkart / stk-code

The code base of supertuxkart
Other
4.53k stars 1.06k forks source link

Icon resizing loses a lot of quality #4959

Open Alayan-stk-2 opened 11 months ago

Alayan-stk-2 commented 11 months ago

Two pictures are enough to explain the issue.

Source image:

nitro

Actual look in game

BadQuality

Notice how the result is very clearly jagged and of unsatisfactory quality despite the input being perfectly fine in this regard.

This can be seen with many other icons, such as the weight icon but it's usually not as obvious as it is here.

Looking at the cartoon theme also makes this issue quite apparent, icons that should be smooth and are based on svg still often look low-quality.

Alayan-stk-2 commented 11 months ago

What seems to happen is that the graphics engine instructs the GPU driver to take the nearest pixel when resizing, which produces this sort of terrible result.

It is also possible to instruct the GPU driver to take the linear average of the closest pixels (if one finds the right place in the graphics code to do it...), but if the original image is much bigger than the target image, this will also fail horribly in much the same way.

The cleanest solution is therefore likely to get icon mipmaps and to have the graphics code give the appropriate instructions to draw the texture using the mipmaps. Mipmaps contain progressively smaller textures (each by a power of 2, so 4 by area, so the total memory cost of a mipmap is 33%), which means that if the target image size is much smaller than the source image size, we don't get the issue of picking four near pixels that are way too close (leading to the same issue as just taking the nearest pixel), as instead the GPU will start from a mipmap texture which is much closer in size to the target size (so the 4 near pixels will be far enough that blending them removes the pixellation).

qwertychouskie commented 11 months ago

A while back I was experimenting with some code that renders the SVG at the exact resolution rather than an arbitrary larger size then scaling it down. Code here: https://github.com/STK-helper/stk-code/tree/SVG-native-res-prototype

Obviously this was just a prototype and more work would be needed to make it work for all icons. However, the advantage is that the SVGs get rendered at exactly the size they are needed, no bigger, no smaller, and therefore scaling artifacts are non-existent.