CubeTexture docs axis confusing/wrong

three.js docs mentions the order of textures is px, nx / py, ny / pz, nz. But I noticed the first value relates to the negative-x axis, not the positive one. This was very confusing and caused me to waste a lot of time trying to figure out what was wrong with my skybox (wrong handedness turns out). I created a https://jsfiddle.net/ebvwxzf2/79/ so you can test it out for yourself.

This is my attempt to illustrate what @nickyvanurk says:

https://codepen.io/boytchev/full/oNVmbOR

The cube in the center has 6 materials, one for each side, and px/nx/py/ny/pz/nz are consistent with the world axes. The background is a cube texture and py/ny/pz/nz are consistent, while px/nx are swapped.

3 Likes

Exactly, thank you very much.

Cube textures have px/nx flipped which is a convention in the library (you can read about the background of this in 3d - Why are the faces of a cubemap labelled px, nx, py, ny, pz, nz? - Stack Overflow).

When you use the sides of the cube map not with CubeTexture, you have to apply the flip by yourself. So the multi-material mesh should be created like so:

var cube = new THREE.Mesh(
		new THREE.BoxGeometry(1,1,1),
		[
			material(imageNX),
			material(imagePX),
			material(imagePY),
			material(imageNY),
			material(imagePZ),
			material(imageNZ),
		]
);

BTW: When assigning the same skybox (the instance of CubeTexture) to Scene.background and the envMap property of a material, the result is as expected.

6 Likes

Thank you very much for this explanation! Now I know why my skybox, when rendered, appears to be rotated 180 degrees the wrong way. Which by convention is actually the correct way. Is there currently a way to rotate a skybox/CubeTexture when used as a scene.background by 180 degrees? Or is waiting for CubeTexture orientation · Issue #16328 · mrdoob/three.js · GitHub or creating a literal box with the sky texture + doubleside rendering the only options I have at this point?

1 Like

Awesome. TIL :smiley:

Just a bit of warning… if you’re building something that is Z up… and you’re trying to make the library accomodate it… There are hard ways, and slightly easier ways to achieve it.

My honest recommendation after being in this situation half a dozen times in my life…
A. convert your code to use Y up if possible.
B. If A isn’t an option… put all your stuff under a single Object3D with a rotation.x = -Math.PI*.5
and use lots of localToWorld and worldToLocal in your logic to make it work.
C. Continue down the path of trying to force threejs to work in a Z up scenario. This path ends in much frustration and gnashing of teeth. Because you will be fighting against… 1. every model importer/exporter that autoconverts to Y up.(like the gltf one)
2. All the controls types (orbitcontrols/flycontrols) etc.
3. All skybox/cubemap/equirectangular env map code. Lord knows if you can even work around this… decompressing images… rotating them. It’s a Complete nightmare. Then there are the many addons 3rd party stuff that have Y up baked in as assumptions. There is the global Up vector in threejs… which you’ll have to reset.

10 years ago, I was a Z-up zealot… since it of course makes perfect sense in a 3d world (it doesn’t)… and I learned the hard way to embrace the native up-ness of the platform… (which turns out to really just be a kinda small shift in perspective and not worth grinding your fingers to nubs to work around for a year only to end up with a pile of janky workarounds…)

(I just re-read the thread and realize that you’re probably not trying to force Z up, but my ptsd about it compelled me to vomit this warning tract.)

2 Likes

I had a good chuckle at your expense, as there’s obviously years of hair pulling trauma behind that post. This is a safe space :smiley:

2 Likes

If you stare into the up vector long enough, the up vector stares back.

1 Like