rememberHDREnvironment

fun rememberHDREnvironment(engine: Engine, initialIntensity: Float, showSkybox: Boolean = true, format: Texture.InternalFormat = Texture.InternalFormat.R11F_G11F_B10F, key: Any = Unit, onError: (Throwable) -> Unit? = null, hdr: suspend () -> ByteArray): Environment

Builds an Environment from an equirectangular HDR image instead of pre-baked KTX — no cmgen step, just ship the .hdr. The reflection cubemap and skybox are prefiltered on the GPU at load via IBLPrefilterContext/EquirectangularToCubemap/SpecularFilter.

The sibling of rememberKTXEnvironment (which loads pre-baked KTX) — same returned type, same scene wiring:

val engine = rememberFilamentEngine()
val env = rememberHDREnvironment(engine = engine) { Res.readBytes("env/lobby.hdr") }
val scene = rememberFilamentScene(
engine = engine,
skyboxState = env.skyboxState,
indirectLightState = env.indirectLightState,
) { GltfInstance(asset = duck) }

Tradeoff vs. rememberKTXEnvironment: there's no baked diffuse irradiance (cmgen's spherical harmonics). Filament approximates diffuse from the reflection's lowest mip — visibly lower quality. Prefer KTX when you can bake offline; use this for raw .hdr workflows. The prefilter runs on the GPU at load, so the first frames render before it lands.

Parameters

engine

Engine the environment's textures are allocated on. Required and first — see rememberKTXEnvironment.

initialIntensity

IBL intensity scale, applied to the state on first composition only — mutate environment.indirectLightState.intensity to change it afterwards.

showSkybox

Render the environment cubemap as the skybox. False = IBL only.

format

Internal format for the decoded HDR equirect texture.

key

Reloads when this changes. Defaults to Unit for static assets.

onError

Invoked once if hdr throws or the bytes can't be decoded as HDR.

hdr

Loader for the equirectangular HDR bytes (2:1 aspect).