Why EXR Is the Real Deal for Skyboxes

Regular images are broken for this
A PNG stores colors as numbers from 0 to 255. That is it. The brightest white and the sun are both 255. But in reality the sun is 10,000x brighter than a white wall. PNG cannot store that. Everything above "white" gets crushed to the same value.
When a 3D engine uses a PNG skybox for lighting, everything looks flat. The sun is not actually bright. The shadows are not actually dark. The light has no real range.
What EXR does differently
EXR stores each pixel as a real floating point number. The sun can be 50000.0. A cloud can be 2.0. A shadow can be 0.003. That is the actual spread of light in the real world, stored in the file.
HDR (.hdr) files do this too, but with a trick. They share one exponent across all three color channels. That means if red is very bright and blue is very dim in the same pixel, blue loses precision. It is a compromise.
EXR gives each channel its own full float. No sharing. No compromise. No precision loss anywhere.
Why this matters
In PBR rendering, the skybox is not just a background picture. It IS the light source. Every material in the scene samples it to figure out ambient lighting and reflections. Metals reflect the sky. Rough surfaces pick up its color. The skybox drives everything.
If the skybox has no real brightness range (PNG), all reflections and lighting look the same. A metal surface reflecting the sun looks identical to one reflecting a cloud. Wrong.
If the skybox has banding in subtle gradients (HDR's shared exponent), those bands show up in every reflection across the scene.
EXR has the full range and full precision. The lighting just works.
How the GPU actually uses it
Three.js takes the EXR skybox and generates blurred versions of it at different levels. Mirror-smooth surfaces sample the sharp version. Rough surfaces sample the blurry version.
This only works when the source has real brightness values. Blurring a PNG averages numbers between 0 and 1. The sun disappears into the blur. Blurring an EXR averages numbers between 0 and 50000. The sun still pumps light into the scene even when heavily blurred. That is what makes rough surfaces glow softly under bright sky. PNG cannot do this.
EXR files are also smaller
HDR files are basically uncompressed. EXR supports lossless compression (ZIP, PIZ). Better quality AND smaller files.
How to use it in Three.js
import { EXRLoader } from 'three/addons/loaders/EXRLoader.js';
const loader = new EXRLoader();
loader.load('sky.exr', (texture) => {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = texture; // The visible sky.
scene.environment = texture; // Lights every PBR material in the scene.
});
Two lines. Every material in the scene now gets correct ambient lighting and reflections from the sky. Automatic.





