Choosing Appropriate Texture Sizes

Inappropriate texture size can lead to wasted resources.

It is a common misconception that bigger textures always look better. A 1024x1024 texture that never takes up more than a 32x32 area of the screen is a waste of both storage space and reduces cache efficiency. A texture’s size should be based on its usage. There should be a one pixel to one texel mapping when the object that it is mapped to is viewed from the closest allowable distance.

Before considering reducing the resolution of texture assets to save storage space, apply texture compression. If the quality of the lossy texture compression is unacceptable, consider using an 8 or 16-bit per pixel uncompressed format. If the storage space for the assets still needs to be reduced, then consider reducing the resolution of the images.

Demystifying NPOT

If a 2D texture has dimensions which are a power-of-two (width and height are 2n and 2m for some m and n), then the texture is known as a POT texture (power-of-two). If they are not, it is known as an NPOT texture (non-power-of-two). This section seeks to clarify the status of NPOT textures in OpenGL ES.

OpenGL ES support

NPOT textures are supported as required by the OpenGL ES specifications. However:

  • NPOT textures are not supported in OpenGL ES 1.1 implementations.
  • NPOT textures are supported in OpenGL ES 2.0 implementations, but only with the wrap mode of GL_CLAMP_TO_EDGE.
    • The default wrap mode in OpenGL ES 2.0 is GL_REPEAT. This must be specifically overridden in an application to GL_CLAMP_TO_EDGE for NPOT textures to function correctly.
    • If this wrap mode is not correctly set, then an invalid texture error will occur. Likewise, a driver error may occur at runtime on newer drivers, to highlight the need to set a wrap mode.

GL_IMG_texture_npot

An extension exists (GL_IMG_texture_npot) to provide some of the functionality found outside of the core OpenGL ES specification. This extension allows the use of the following filters for NPOT textures:

  • LINEAR_MIPMAP_NEAREST
  • LINEAR_MIPMAP_LINEAR
  • NEAREST_MIPMAP_NEAREST
  • NEAREST_MIPMAP_LINEAR

It also allows the calling of glGenerateMipmapOES with an NPOT texture to generate NPOT mipmaps. Like all other OpenGL ES extensions, the application should check for this extension’s presence before attempting to load and use it.

Guidelines

Additional points to consider when using NPOT textures:

  • POT textures should be favoured over NPOT textures for the majority of use cases, as this gives the best opportunity for the hardware and driver to work optimally.
  • A 512x128 texture will qualify as a POT texture, not an NPOT texture, where rectangular POT textures are fully supported.
  • 2D applications should see little performance loss from the use of NPOT textures other than possibly at upload time. 2D applications could be a browser or other application rendering UI elements, where an NPOT texture is displayed with a one-to-one texel to pixel mapping.
  • To ensure that texture upload can be optimally performed by the hardware, use textures where both dimensions are multiples of 32 pixels.

The use of NPOT textures may cause a drop in performance during 3D rendering. This can vary depending upon mipmap levels, size of the texture, texture usage, and the target platform.