User Manual


A texture is an image. For use in WebGL, the texture’s dimensions must be a power of 2 ( 128, 256, 512, 1024, 2048, 4096…). The texture can be square (eg 512 x 512 ) or rectangular (eg 256 x 1024 ).

Textures have many uses:

  • they can simply be used in a material to color the object it is applied to
  • they can encode information in order to modify the look of a material, eg a texture can show where an object is more metallic and where it is rougher, or it can show where in the object are bumps
  • they can be fed into shaders as inputs to generate more complex or animated visuals
  • they can contain information such as spatial positions and be read by a vertex shader
  • they can contain arbitrary data which can be transformed by the GPU, enabling processes such as complex physics simulations or even things that aren’t related to graphics at all (browser based machine learning libraries such as TensorFlow.js actually use WebGL shaders rendering computations to textures)


JPEGs and PNGs are currently supported.


We need to optimise textures in order to get the best loading time (minimal file size) as well as the best performance, while preserving visual quality.

JPEGs should be used for any texture that does not require an alpha channel (textures that don’t have any transparent parts).

In order to easily convert images to different formats and resize them, you can use sips (mac), imagemagick ( cross-platform ), ffmpeg ( cross platform, also useful for video and audio manipulation).

Other free optimisation tools include ImageAlpha ( lossy compression for PNGs ) and ImageOptim ( strips image files of metadata ).

3D models typically use several textures: Metallic + Roughness, Normal and Color. One possible trick is to not use the same size of texture for each of these: you could use a 512×512 normal map, and a 1024×1024 color map. The best combination will vary depending on the textures’ amount of detail.

Watch out

  • While your texture may have a tiny file size, like a black and white JPEG with very little detail, it will be decompressed on the GPU. This means that a 10KB 1024×1024 JPEG will use the same amount of memory on the GPU as a 1MB 1024×1024 JPEG. KTX textures are a way to deal with this, as they stay compressed on the GPU. However they introduce a certain amount of complexity and are not yet supported by XR.Club.
  • Be wary of texture size limitations, especially on iOS mobile devices. Larger texture sizes (4096×4096 upwards) may not always be supported, and in most cases are not needed. As an example, even on larger desktop screens, skyboxes using 1024×1024 textures usually look good enough.
  • If your mobile device keeps reloading the page after warning about an error, but nothing is showing up in the developer console, this might be due to the device running out of memory. Make sure that you aren’t using too may textures, and that their sizes are reasonable.


THREE.js texture documentation