fromEquirectHdr static method
Future<EnvironmentMap>
fromEquirectHdr({
- required Float32List linearPixels,
- required int width,
- required int height,
- List<
Vector3> ? diffuseSphericalHarmonics,
Builds an EnvironmentMap from a high-dynamic-range equirectangular
radiance map: linear (not sRGB) RGBA float pixels, row-major,
width by height.
Unlike fromUIImages, the input is linear HDR, so radiance above 1.0
(bright skies, the sun) is preserved through the prefilter and lights
the scene at its true intensity. Pass diffuseSphericalHarmonics to
supply your own diffuse term instead of projecting it.
Implementation
static Future<EnvironmentMap> fromEquirectHdr({
required Float32List linearPixels,
required int width,
required int height,
List<Vector3>? diffuseSphericalHarmonics,
}) async {
assert(linearPixels.length == width * height * 4);
// The radiance texture is fp16, not fp32: the prefilter samples it
// with a linear sampler, and 32-bit-float textures are not filterable
// on several GPU backends (notably Apple Silicon), which would make
// the prefiltered atlas read back as black. fp16 is universally
// filterable and carries ample range for radiance.
final radianceTexture = gpu.gpuContext.createTexture(
gpu.StorageMode.hostVisible,
width,
height,
format: gpu.PixelFormat.r16g16b16a16Float,
)..overwrite(ByteData.sublistView(_floatPixelsToHalf(linearPixels)));
final prefilteredRadiance = prefilterEquirectRadiance(
radianceTexture,
sourceIsLinear: true,
);
final sh =
diffuseSphericalHarmonics ??
_projectLinearEquirectToSphericalHarmonics(linearPixels, width, height);
return EnvironmentMap._(prefilteredRadiance, sh);
}