playcanvas / playcanvas/engine

V3: remove six-cubemap prefiltered IBL input (prefilteredCubemaps / skyboxPrefilteredN)

Open
#9,325 1 comment 0 reactions 1 assignee View on GitHub

@mvaligursky is already working on this.

Since Sep 8, 2026.

area: graphics enhancement V3
Dominant language
JavaScript
Stars
16.8k
Forks
2k
Avg merge
4h 32m
Merged PRs (30d)
222

Description

Summary

The engine still accepts image-based lighting as a set of six prefiltered cubemaps (128, 64, 32, 16, 8, 4) and converts them on the GPU into an env atlas at assignment time. Since the env atlas is the only format the lit shaders sample, this input path is a legacy adapter carried in core. Proposal: drop it in V3 and, if needed, offer the conversion as a helper in extras.

Current state

Public entry points that accept the six-cubemap array

  • Scene#prefilteredCubemaps (src/scene/scene.js) – runs EnvLighting.generatePrefilteredAtlas and stores the result in an internal _internalEnvAtlas.
  • Scene#setSkybox(cubemaps) – when element 1 is a cubemap (not an atlas), forwards cubemaps.slice(1) to prefilteredCubemaps.
  • StandardMaterial#prefilteredCubemaps (src/scene/materials/standard-material.js) – same conversion, writes material.envAtlas.
  • Cubemap asset handler (src/framework/handlers/cubemap.js) – splits a legacy DDS prelit cubemap into six per-level cubemap textures and places them in asset.resources[1..6]; AppBase#setSkybox and the material handler's _assignCubemap then feed those into the setters above.

Deprecated per-level accessors

  • Scene#skyboxPrefiltered128/64/32/16/8/4 (@deprecated, @ignore, still emitted in the d.ts). These write straight into _prefilteredCubemaps[i] and set updateShaders, bypassing the atlas regeneration and _resetSkyMesh(). They have no effect on lighting at all, and only affect the skybox if something else later rebuilds the sky mesh. Their getters return undefined on any scene set up through envAtlas, which is the path the Editor and asset pipeline use today.

Shader side

  • No shader chunk samples the six prefiltered cubemaps. Lit shaders only read texture_envAtlas. reflectionCube samples a single texture_cubeMap with a non-LOD lookup for material cubeMap / bare scene skybox.
  • The only unconverted use is Scene#_getSkyboxTex, which picks one of the six as the skybox texture when skyboxMip > 0 (with the long-standing "skip the 32x32 level" quirk).

Proposal for V3

  1. Remove Scene#skyboxPrefiltered128..4 outright. They are already broken for lighting.
  2. Remove Scene#prefilteredCubemaps and StandardMaterial#prefilteredCubemaps. The engine's only IBL input becomes envAtlas.
  3. Simplify Scene#setSkybox (or remove it in favour of scene.skybox + scene.envAtlas).
  4. In the cubemap asset handler, either stop synthesising the six per-level cubemaps from DDS, or convert them to an env atlas once at load time and expose only [cubemap, envAtlas] in asset.resources.
  5. Re-evaluate skyboxMip: with no prefiltered cubemaps it would always drive the atlas mipLevel uniform, which also lets us drop the skipped-32x32 mapping quirk.

Migration

If existing users still have six-cubemap data (e.g. older DDS prefiltered assets), provide a small helper in extras that wraps EnvLighting.generatePrefilteredAtlas:

import { prefilteredCubemapsToEnvAtlas } from 'playcanvas/extras';
scene.envAtlas = prefilteredCubemapsToEnvAtlas(device, cubemaps);

This keeps the conversion available without carrying it in core Scene / StandardMaterial.

Notes

  • EnvLighting.generatePrefilteredAtlas itself stays; it is also used for atlas generation from a source cubemap.
  • Editor and developer-site docs should be checked for references to prefilteredCubemaps / setSkybox before removal.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.