Why you should optimise your textures

Let’s talk texture optimisation.

With textures, you’ll always be balancing the three core constraints of rendering speed, device performance and image quality. The rule of thumb is to keep your textures to the max size they need to be seen and no more.  Yes, it’s a pain to have to nip into Photoshop or Gimp to resize but it’s one of those things that sometimes just has to be done if you don’t want your user’s device to choke on the download.

So here’s a bit of background information on texture rendering and a few tips to improve your results. This is only a potted tour of the various topics, if you want more information go searching and be amazed at how much technical information is out there.  The more you know, the better your output will be but this too is a trade-off between the time needed to optimise to the max and releasing your item.

Does size really matter?

Yes, in this case size matters.  The larger the image, the more memory it will use when trying to render it on the screen.  For example, a 1024 x 1024 image uses 3MB of video card memory to render and more if there’s an alpha channel.  If you’ve used 50 textures that are 1024 x 1024 in your scene you’ve got a lot of video memory processing happening, particularly for handhelds and older desktops and laptops.

At best, it may just cause a fps drop (lag) during rendering on devices that have smaller memory capabilities for no good reason but at worst, it will crash the application as the video memory just can’t process what you’re throwing at it.

In case you’ve not seen the stats,

  • a 256×256 image will load 4 times faster than a 512×512 image,
  • a 512×512 image will load 4 times faster than a 1024×1024
  • a 256×256 will load 16 times faster than a 1024×1024.

The trade-off is quality (detail) against speed.

This is more of a problem for games than for modelling tools, as with modelling tools all rendering is done before the scene is used.  However, rendering times can be impacted by large texture sizes so optimising the size should be good practice for everyone.

That’s why the [NDC] textures are usually 512 x 512 up to a max of 512×765 which is plenty big enough for detail without having to modify them and can be resized down, to apply to smaller objects.

What size resolution should I use?

This is tricky as it depends on so many factors.  Resolution is the measurement of the number of pixels in the display in width x height.  Therefore, a monitor that has a resolution of 1920 x 1080 ppi is 1920 pixels wide x 1080 pixels high.  To add to the angst when talking about resolution, some monitors have a lower resolution than the screen size and the ppi they can display will be higher than the standard 72ppi.

You need to identify where your build will be used, desktop, mobile, laptop, tablet, each of them has a different popular screen resolution.  You should consider building to the relative size of the object in largest resolution you expect to render on, it’s easy to compress but if the image display is increased to larger than your image size, it will lose definition, or in the case of web pages, the image display will be reduced in proportion to the size of the page.

http://statcounter.com/ say that as of Nov 2017 the percentage of devices used was:

Mobile – 50.02%

Desktop – 45.68%

Tablet – 4.3%

And of course within that are many different screen resolutions.  Ultimately, it’s a bit of a dark art, so you need to know  your audience.

Does colour mode matter?

RGB is designed for screens and uses red, green and blue as the base colours.  CMYK used for print.  With RGB, the device will determine how the RGB value is displayed, which is why an image that looks fantastic on your screen can looks shabby on someone else’s.

The other thing to note is the ppi/dpi for the two types is different.  Print always needs 300dpi for sharp printing whereas RGB is usually 72ppi as most monitors will only display 72ppi.

[NDC] textures are made in 8bit RGB.  Sometimes texture makers will up the bits to give themselves more colour options. 8bit gives you 256 different shades for each of the colour channels whereas 16bit gives you 65,536 colours per channel.  That sounds fabulous until you realise that the vast majority of screens can only show 8bits per channel anyway (there are a few that show 10bits but these are specialist and not readily available for consumers), so any finer colour are lost as the screen will only show those colours in its 8bit range.

What about block compression?

Block compression is used in many mobile and online games as it reduces the size of the file and reduces the amount of memory needed to process it.  There’s no overhead for decompression and of course there’s the performance gain from having a smaller file.

If you’re using a compression tool, chose it carefully as each of them is tailored to a particular type of file.

What’s this ‘power-of-two’ thing?

Back in the day, OpenGL couldn’t handle textures that weren’t sized to the power-of-two (Po2), i.e. all textures had to be an even number sized and ideally within the magic numbers (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024.. you get the drift).

OpenGL can now handle odd sizes but despite advances in hardware and software, some graphics cards, particularly the older cards, still can’t handle odd sized textures. So, to ensure everyone can render, the power of 2 is a good rule of thumb to use as there are still some games that will either pad the non power-of-two up to the nearest Po2 or reduce it. You’re much better off doing it yourself as you have control of how it will look, rather than relying on the game engine to do it.

Tips

These are particularly useful if the texture is being downloaded or streamed.

Use a smaller texture and tile

If you can tile a smaller texture rather than using one big one you’ll substantially reduce the video memory load – there is a slight overhead as the device processes the tiling request but it’s usually not as much as processing large textures

Reuse the texture on other objects

If you can reuse the texture in a scene, do it.  That way the texture is only downloaded once and then applied everywhere you’ve specified. Again, you’ll improve performance and load speeds. Even if the texture is cached, there’ll be a reduction in the render time as the app isn’t having to redraw as many unique textures, so should improve your fps in the scene.

Where are you using your texture?

If it’s a box on a table that is just a backdrop to the scene then the resolution can be lower.  At best, people may do nothing more than glance at it and move on, so a high res texture with lots of detail is just a waste of time and only adds lag to the scene as the video card memory tries to process it.

If it’s going to be inspected carefully as it’s key to a scene, then you might increase the resolution to the max screen size it will be displayed at, as people will be zooming in for a closer look.  Only do it for important objects in the scene, as you don’t want to be bogging down everyone’s texture loads just because someone might want to look at a doorknob that is only there to add realism because doors have doorknobs.

How much of the screen does it take up in the scene?

If your expected screen resolution is say 1920×1080 ppi using a 1024 x 1024 texture on your box on the table is overkill as it’s probably only going to take 5% of your scene on the screen.  If you’re working in pixels (ppi) then count the number of pixels you expect to use in the default render and rescale to a little bigger than that if your users will zoom in a bit.

If the texture is going to take up the entire screen, then you might want to go bigger, say a 2048 x 1024, which means it will cover the entire screen without distortion.

Follow