CubeTexture and Skyboxes

A CubeTexture holds six square faces addressed by direction: new BABYLON.CubeTexture('textures/sky', scene) loads sky_px.jpg to sky_nz.jpg, and a single .env or .dds file works too. A skybox is a large inside-out cube whose StandardMaterial uses the cube with coordinatesMode = BABYLON.Texture.SKYBOX_MODE, backFaceCulling = false and disableLighting, on a mesh with infiniteDistance, so it never gets closer. The helper does all of that:

A skybox from an environment textureJavaScript
const env = BABYLON.CubeTexture.CreateFromPrefilteredData('booknest-sunrise.env', scene);
const skybox = scene.createDefaultSkybox(env, true, 200, 0.05);  // PBR, 200 m box, 5% blur
console.log(skybox.name, skybox.infiniteDistance, skybox.material.getClassName(),
  skybox.material.reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE);
Output
hdrSkyBox true PBRMaterial true

blur samples a rougher mip level of the prefiltered cube. Keep the box inside the camera's maxZ, and out of picking and shadows.

A sunrise cube texture as a skybox around a BookNest kiosk, reflected in a chrome globeHTMLLive
<!doctype html>
<style>
  body { margin: 0; background: #f7f3ec; font: 13px system-ui, sans-serif; color: #333; }
  canvas { width: 100%; max-width: 600px; height: 330px; display: block; touch-action: none; outline: none; }
  #info { max-width: 600px; padding: 4px 8px; font-family: monospace; }
</style>
<canvas id="view"></canvas>
<div id="info"></div>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script>
// A procedural HDR sunrise sky, computed texel by texel into six float faces. It stands in for
// an .hdr or .env download, which this sandboxed preview cannot fetch.
function createSkyTexture(scene, size = 128) {
  const sunDir = new BABYLON.Vector3(0.45, 0.28, 0.85).normalize();
  const faceDirection = [                           // (s, t) in -1..1 to a direction, per face
    (s, t) => [1, -t, -s], (s, t) => [-1, -t, s], (s, t) => [s, 1, t],
    (s, t) => [s, -1, -t], (s, t) => [s, -t, 1], (s, t) => [-s, -t, -1]];
  const faces = faceDirection.map((toDirection) => {
    const data = new Float32Array(size * size * 4);
    for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {
      const [dx, dy, dz] = toDirection((2 * x + 1) / size - 1, (2 * y + 1) / size - 1);
      const len = Math.hypot(dx, dy, dz), up = dy / len;
      const k = Math.sqrt(Math.max(up, 0));            // 0 at the horizon, 1 straight up
      const ground = Math.min(Math.max(-up * 8, 0), 1);   // fade to the ground below the horizon
      const r = (1 - 0.62 * k) * (1 - ground) + 0.36 * ground;    // peach horizon, blue zenith,
      const g = (0.82 - 0.22 * k) * (1 - ground) + 0.3 * ground;  // warm brown ground
      const b = (0.68 + 0.3 * k) * (1 - ground) + 0.24 * ground;
      const cosSun = Math.max((dx * sunDir.x + dy * sunDir.y + dz * sunDir.z) / len, 0);
      const sun = 30 * Math.pow(cosSun, 900) + 0.35 * Math.pow(cosSun, 24);   // disc + glow, HDR
      const i = (y * size + x) * 4;
      data[i] = r + sun; data[i + 1] = g + sun * 0.85; data[i + 2] = b + sun * 0.6; data[i + 3] = 1;
    }
    return data;
  });
  const sky = new BABYLON.RawCubeTexture(scene, faces, size, BABYLON.Constants.TEXTUREFORMAT_RGBA,
    BABYLON.Constants.TEXTURETYPE_FLOAT, true, false, BABYLON.Constants.TEXTURE_TRILINEAR_SAMPLINGMODE);
  sky.gammaSpace = false;                            // linear HDR values, like a loaded .hdr
  return sky;
}

const canvas = document.getElementById('view');
const engine = new BABYLON.Engine(canvas, true);
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera('cam', -Math.PI / 2 + 0.5, 1.45, 7, new BABYLON.Vector3(0, 1, 0), scene);
camera.attachControl(canvas, true);
camera.useAutoRotationBehavior = true;
camera.autoRotationBehavior.idleRotationSpeed = 0.15;

// The book loads new BABYLON.CubeTexture('textures/sky', scene) or a single .env file;
// here the six faces are computed in code and blurred into a prefiltered mip chain
const env = createSkyTexture(scene);
new BABYLON.HDRFiltering(engine).prefilter(env);
scene.environmentTexture = env;
const skybox = scene.createDefaultSkybox(env, true, 200, 0.05);   // PBR, 200 m box, 5% blur

// A kiosk of books on a paved square
const ground = BABYLON.MeshBuilder.CreateDisc('ground', { radius: 8, tessellation: 48 }, scene);
ground.rotation.x = Math.PI / 2;
const pbr = (name, hex, roughness, metallic = 0) => {
  const m = new BABYLON.PBRMaterial(name, scene);
  Object.assign(m, { albedoColor: BABYLON.Color3.FromHexString(hex), roughness, metallic });
  return m;
};
ground.material = pbr('paving', '#b9ab98', 0.9);
const stand = BABYLON.MeshBuilder.CreateBox('stand', { width: 2.4, height: 0.9, depth: 1 }, scene);
stand.position.y = 0.45;
stand.material = pbr('wood', '#6d4c33', 0.7);
['#1f5f8b', '#5b3f99', '#e09a10', '#3f7d3a', '#b5452f'].forEach((hex, i) => {
  const book = BABYLON.MeshBuilder.CreateBox('book' + i, { width: 0.36, height: 0.52, depth: 0.08 }, scene);
  book.position.set(-0.9 + i * 0.45, 1.16, 0);
  book.rotation.x = -0.2;
  book.material = pbr('cover' + i, hex, 0.45);
});
const globe = BABYLON.MeshBuilder.CreateSphere('globe', { diameter: 1.1, segments: 48 }, scene);
globe.position.set(2, 0.55, 0.6);
globe.material = pbr('chrome', '#ffffff', 0.05, 1);      // a mirror of the cube texture

document.getElementById('info').textContent = `${skybox.name}: infiniteDistance ${skybox.infiniteDistance}, ` +
  `${skybox.material.getClassName()}, SKYBOX_MODE ` +
  `${skybox.material.reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE}`;
engine.runRenderLoop(() => scene.render());
addEventListener('resize', () => engine.resize());
</script>