Compressed Basis Textures for Cube Maps - Skybox

Hi there :raised_hand:

Im trying to create a skybox using a cube map of 6 images 2048x2048. Obviously that can be quite heavy and I was looking forward to getting that sweet basis compression. :yum:
After all it seemed to me like a great use case.
To my horror it turns out THREE.CubeTexture cannot be made with compressed textures!? :scream:

image
(single images work correctly)

I’ve found THREE.CubeTexture using THREE.CompressedTexture - #13 by Mugen87 and tried the PR code WebGLTextures: CubeTexture from CompressedTextures signature bug by oguzeroglu · Pull Request #16648 · mrdoob/three.js · GitHub, but had no success :slightly_frowning_face:

Has there been any progress on this? If not, then is there any workaround to getting a skybox through basis compressed textures? Something different than a CubeTexture applied to scene.background?

Thanks :slight_smile:

No. We had to revert the PR since other example code was broken after the merge. Unfortunately, nobody has investigated the issue in detail so far.

Can you please demonstrate the issue with live example or github repository? I can have a look.

Thanks a lot :relaxed:

https://github.com/DolphinIQ/compressed-cubetexture

Ive added original images before and after basis compression. There is also my basisu.exe that I used.

I’ve created a PR with a fix:

It should be now possible to create the cube map in your example code like so:

const cubeMap = new THREE.CubeTexture( [ right, left, up, down, front, back ] );

cubeMap.minFilter = right.minFilter;
cubeMap.magFilter = right.magFilter;
cubeMap.format = right.format;
cubeMap.encoding = right.encoding;

cubeMap.needsUpdate = true;

cube.material.envMap = cubeMap;
cube.material.needsUpdate = true;

scene.background = cubeMap;
4 Likes

Thanks, you’re awesome!
Load time and memory usage went nicely down :partying_face:

2 Likes

can you share your working sample again?

get a simple example working with

 var loader = new THREE.BasisTextureLoader();
    loader.setTranscoderPath("/libs/basis0/");
    loader.detectSupport(scene.renderer);

    const path = "/assets/cubemaps/underwater/";

    await Promise.all([
      new Promise((resolve, reject) => loader.load(path + "posx.basis", resolve, undefined, reject)),
      new Promise((resolve, reject) => loader.load(path + "negx.basis", resolve, undefined, reject)),
      new Promise((resolve, reject) => loader.load(path + "posy.basis", resolve, undefined, reject)),
      new Promise((resolve, reject) => loader.load(path + "negy.basis", resolve, undefined, reject)),
      new Promise((resolve, reject) => loader.load(path + "posz.basis", resolve, undefined, reject)),
      new Promise((resolve, reject) => loader.load(path + "negz.basis", resolve, undefined, reject))
    ]).then(([posx, negx, posy, negy, posz, negz]) => {
      const cube = new THREE.CubeTexture([posx, negx, posy, negy, posz, negz]);

      cube.minFilter = posx.minFilter;
      cube.magFilter = posx.magFilter;
      cube.format = posx.format;
      cube.encoding = posx.encoding;

      cube.needsUpdate = true;

      scene.background = cube;
    });

Does it work now? Your code looks good. This issue fix was merged into r113, so you don’t have to edit any files anymore.
Btw you might wanna add posx.encoding = THREE.sRGBEncoding; before creating the CubeTexture if you want to work in sRGB colorspace.

1 Like