Load Mipmaps Manually in Three.js CompressedTexture

This article explains how to manually load specific mipmap levels into a CompressedTexture in Three.js. You will learn how to structure your raw binary mipmap data, assign it to a custom texture object, and configure the rendering filters to ensure Three.js utilizes your custom mipmap levels correctly.

To manually load and assign mipmap levels to a CompressedTexture, you must pass an array of mipmap objects directly to the texture. Each object in this array must contain the raw pixel data (TypedArray) for that specific level, along with its corresponding width and height.

Here is the complete step-by-step implementation:

import * as THREE from 'three';

// 1. Prepare your raw compressed binary data for each mipmap level
// In a real scenario, these Uint8Arrays are parsed from a KTX, DDS, or Basis file.
const mipLevel0Data = new Uint8Array([/* ... raw binary data ... */]); // 512x512
const mipLevel1Data = new Uint8Array([/* ... raw binary data ... */]); // 256x256
const mipLevel2Data = new Uint8Array([/* ... raw binary data ... */]); // 128x128

// 2. Structure the mipmaps array
const mipmaps = [
  { data: mipLevel0Data, width: 512, height: 512 }, // Base level
  { data: mipLevel1Data, width: 256, height: 256 }, // Mip level 1
  { data: mipLevel2Data, width: 128, height: 128 }  // Mip level 2
];

// 3. Define the texture parameters
const width = 512;
const height = 512;
const format = THREE.RGBA_S3TC_DXT5_Format; // Use the matching GPU compression format

// 4. Instantiate the CompressedTexture with the mipmaps array
const compressedTexture = new THREE.CompressedTexture(
  mipmaps,
  width,
  height,
  format
);

// 5. Enable mipmap filtering
compressedTexture.minFilter = THREE.LinearMipmapLinearFilter;
compressedTexture.magFilter = THREE.LinearFilter;

// 6. Notify the renderer to upload the texture to the GPU
compressedTexture.needsUpdate = true;

Key Requirements for Success