Thanks both for the quick and thoughtful answers! If you don’t mind, please correct errors in my understanding? (I’m sure I got some things wrong!)
(general graphics background)
In a scene, there are (at least) two major uses for “environment maps” (panoramic images capturing the view in all directions).
A “skybox” to capture very-far-away scenery – clouds, distant mountains, etc – to paint onto a flat box around the world. (Kind of like fake-sky-domes in the Truman Show or the Hunger Games, or scenery “flats” in a stage play.) It’s imperfect because there’s no parallax, but if the skybox objects are very far away that’s okay, and flat images are way faster than actually rendering all those clouds and mountains and stuff.
A “reflection map” that captures the view (of both near and far objects) from the vantage of a particular object, and gets warped and pasted onto the object (based on the camera’s vantage and the object’s shape) to simulate reflective surfaces (a mirror, shiny spoon, etc). This is again imperfect because there’s no parallax, but for reflective objects which are smaller than their surrounding this is okay, and it’s a lot faster than a complete re-render for the reflection (e.g. via raytracing).
(Babylon.js / GL specifics)
In Babylon.js, both use cases for environment mapping use some common mechanisms:
The “CubeTexture” class, which represent an image-based environment map. (The base CubeTexture uses six square images, subclasses take other inputs.) Note, though it’s a “texture”, it can’t be used in every place “ordinary” textures can be used.
The “reflectionTexture” property on Material, which holds an environment map (e.g. a CubeTexture) to be painted on surfaces, as if they were situated in and reflecting that environment.
For a reflective object – a shiny spoon, say – one might make a CubeTexture picturing the scene around the spoon, and assign it to the spoon’s material’s reflectionTexture. Very logical!
For a skybox, one might use a CubeTexture as a handy way to load six images (or some other panoramic-image format) into a box. (Or one might use ordinary UV mapping to paint a regular texture onto the skybox cube.) One would NOT expect to use reflectionTexture for a skybox, since a skybox isn’t “reflecting” anything, it’s just a big fake sky…
BUT, Babylon does not support using a CubeTexture as an “ordinary” texture (diffuse, emissive, specular) on an object, only as a reflectionTexture. THUS, if you want the convenience of using a CubeTexture to load a panoramic image for a skybox, you have to use it as a reflectionTexture.
BUT BUT, we don’t want to “reflect” the environment on the skybox – we want to show it directly, not act as if the skybox were a giant mirror. So we set coordinatesMode=SKYBOX_MODE on the CubeTexture, which says to “reflect” as if the environment is pasted directly on the object (not actually a reflection at all). In general, coordinatesMode controls how reflections are computed (does it have any effect on non reflection textures?).
(Again, for a skybox, one could apply the cube images to the sides of a cube as a classic emissiveTexture with appropriate UV mapping and sidestep the whole issue, but CubeTexture is very convenient, so setting reflectionTexture to a CubeTexture with coordinatesMode = SKYBOX_MODE is the standard way to make a skybox in Babylon.js.)
(Arguably it might be more sensible for CubeTexture and MirrorTexture and such to not be considered “textures” at all, but called something like “environment images”, and to have a material property like environmentMap to use them, and replace coordinatesMode with environmentMapMode, since as far as I can tell there’s no real commonality between “ordinary” textures and “environment” textures. But that’s not how Babylon is structured, partially because that’s not how GL is structured??)
Is some of that even close to right?? (Thanks again for your help!)