Hi, I generate 6 images in a web worker and use them as follows:
const segments = 10;
const geometry = new BoxGeometry(1, 1, 1, segments, segments, segments);
const materials: MeshBasicMaterial[] = [];
for (let i = 0; i < 6; i++) {
// bitmaps is an array of ImageBitmap, transferred from the web worker
const map = new CanvasTexture(bitmaps[i]);
map.minFilter = LinearFilter;
map.colorSpace = SRGBColorSpace;
materials.push(
new MeshBasicMaterial({
side: BackSide,
transparent: true,
depthWrite: false,
opacity: 0.8,
blending: AdditiveBlending,
map
})
);
}
const mesh = new Mesh(geometry, materials);
When I display the images in order (the bitmaps
array element order is px,nx,py,ny,pz,nz
), I get a correct cube map:
But when I render the cube, it’s messed up:
What am I doing wrong here? 
Can you try to create a CubeTexture
based on your images and apply it to the envMap
material property instead? Check out how webgl_materials_envmaps does it.
Thanks for your reply @Mugen87, I was thinking about it, but I can’t seem to find a way to create a CubeTexture
directly from the ImageBitmap
s, as far as I can see it only accepts image object, which means that I have to loop through all the ImageBitmaps, draw them on a canvas, then create a new image from the canvas’ toDataURL()
. If that’s the only way, then I guess I will go with that of course 
My confusion is coming from the fact, that before I moved the texture generation to the web worker, it was something like this:
for (let i = 0; i < 6; i++) {
material.uniforms.uIndex.value = i;
maps.push(
new THREE.MeshBasicMaterial({
side: THREE.BackSide,
transparent: true,
depthWrite: false,
opacity,
map: cubeMap.getMap(material)
})
);
}
where cubeMap.getMap(material: ShaderMaterial)
would render a plane to a WebGLRenderTarget
and return its .texture
, and it was working fine, everything was correct.
I’m using the exact same code in the worker for rendering the texture, just not to a render target, but to an OffScreenCanvas
, that’s the first difference, the second one is using CanvasTexture
for the map, instead of Texture
. Maybe one of these causes the issue?
Any chances to share a live example that shows what you are doing? I would like to experiment a bit with this issue.
Definitely, I will put something together soon, thank you!
@Mugen87 so here’s a working example, maps rendered correctly: box-cube-map-main-thread
And the other one (I skipped the web worker part, but I think it still demonstrates it well): box-cube-map-worker
So, after digging a bit more, noticing that flipY = false
makes no difference at all, and somehow stumbling upon ImageBitmapLoader
and this text:
Note that Texture.flipY and Texture.premultiplyAlpha with ImageBitmap are ignored. ImageBitmap needs these configuration on bitmap creation unlike regular images need them on uploading to GPU.
I went ahead and modified the example, so the ImageBitmap
is flipped (unfortunately it adds Promises and some extra steps into the mix) and it solves the issue: box-cube-map-worker-flip 
1 Like