Dealing with Sketchfab's normal map compression

Tutorial / 06 August 2018

If you've ever tried loading a shiny normal mapped low poly object to Sketchfab, you might have noticed the horrendous compression artifacts you get not in the editor but in the viewer. Worst thing about it is that the editor uses uncompressed textures which are also visible in the viewer after saving and exiting. That's because the compression is not done locally on the user's machine but on Sketchfab's servers. It takes a couple of hours before the textures get compressed, at which point the model transforms and looks pretty bad (1). This means most users don't bother to recheck the textures after compression and are not aware of the quality degradation that occurs.

Here's an example:

To reduce this, you could try forcing the viewer to download the uncompressed textures by appending this to your link (2):


So the link for the Chevy Pickup will look like this:

As you can see below, the textures look a lot better. The great news is that you can also append this to the short links and use them when embedding in a Artstation page or blog post!

There's another layer of confusion if you're working with 16 bit images hoping to get around the compression somehow. It's the fact that Sketchfab does not dither the 16 bit image when taking it down to 8 bit before compression. At the time of this article, Sketchfab does not support 16bit normal maps, although they are working on it. So importing 16bit pngs are a no go, there's no quality benefit from uploading these.

Last layer of confusion is for users of Substance Painter. If you work in 16bit and you use Painter to upload directly to Sketchfab, you might have noticed that when exporting with the Sketchfab preset, you get locked out of controlling the texture file format and bit depth:

Although the format reads JPEG, the normal maps are saved in PNG format without compression to avoid dual compression when uploading to Sketchfab. The dithering issue is still there though, Substance Painter does not dither the file when reducing the bitdepth so you get banding artifacts. Here's a comparison between the PNG exported from Painter with no dither and one exported in 16bit and then manually reduced to 8bit with dithering in Photoshop by using Image->Mode->8 Bits/Channel.

So there are two problems here: Sketchfab's normal map compression and the 16bit to 8bit compression issues. Depending on how you work, I would suggest the following depending on your initial normal map bakes:

8 Bit / Channel bakes:

I would advise against working with 8bit bakes but if by any chance you HAVE too or you already have a bunch of assets that were created from start to finish in 8 bit and don't want to rebake, using the ?image_compression=0 trick above will help improve final quality.

16 Bit / Channel bakes:

I advise using 16 bit normal maps for as much of the pipeline as possible and only reduce the textures to 8 bit / channel when the final normal map is completed. This ensures you get the maximum amount of information in your normal maps through-out the texturing process. 

a. Bake the normal map in 16 bit.

I use Marmoset Toolbag 3 for my bakes but most bakers such as Substance Painter and Designer as well as xNormal support 16 bit normal map baking.

b. Texture in 16 bit.

If you're using Painter make sure you're still working in 16 bit. It should be on by default. This will make the generators and filters that use the normal map take advantage of the increased bit depth to create smooth effects.

PS: If you're using Photoshop or any other texturing tool, also make sure to be working with 16 bit normal maps through-out the texturing process.

c. Export the final normal map in a format that supports 16bit.

Here's an example for Substance Painter:

d. Open the normal map in Photoshop and reduce the bit depth. Dithering will be applied automatically:

If you want to get the maximum quality from Sketchfab, you can export using the Substance Painter plugin but then in the Sketchfab editor replace your normal maps with the ones you saved at c. and d. above. Idea taken from this thread (3).

Finally, you want to use the ?image_compression=0 links to share your work!

References and further reading: