A hands-on look at how EV100 maps exposure to luminance, built interactively instead of just explained.
I have been fascinated by the EV100 implementation by Sébastien Lagarde and Charles de Rousiers. I have used it indirectly before through engine settings, but never actually looked at the math or code behind it. This post is what I learned when I finally did, and how I turned it into something I could play with.
From photography to digital lighting: the Sunny 16 rule
The Sunny 16 rule is one of the oldest exposure guidelines in photography: on a bright sunny day, set your aperture to f/16 and your shutter speed to the reciprocal of your ISO. At ISO 100 that means f/16 at 1/100s. No meter needed, and it just works because it is grounded in the same physics as everything else.
This is useful for lighting artists because it maps directly to EV100. The relationship between f-stop, shutter speed, and ISO can be expressed as:
Plugging in the Sunny 16 values (𝑁 =16, 𝑡 =1/100, 𝑆 =100):
So a bright sunny exterior sits at roughly EV 15. That single anchor point gives you a whole reference ladder to work from:
Scene values follow a standard photography EV table at ISO 100. Luminance comes from 𝐿 =2𝐸𝑉100 ⋅12.5/100, matching Table 7 of "Moving Frostbite to PBR".
If you have spent time shooting outdoors, you already have an intuition for what f/11 versus f/16 feels like, and that intuition translates. An overcast sky is about two to three stops darker than full sun, which is exactly what the table above reflects. When you build a lighting scenario in Unreal or any physically based renderer, you can start from EV 15 for your key light and work outward from there, rather than guessing at lux values from scratch.
What EV100 is and why it matters
EV100 is grounded in the rules of photography, which gives us a way to standardize lights in a scene. Eyeballing it will never give you the accuracy you want. By following the scientific route, you can make sure a lighting scenario holds up whether it is indoors or outdoors, or compensate for the difference on purpose.
By calculating the luminance of your lights against a certain EV value, every light in the scene is set up against the same reference, so they stay consistent with each other.
It matters beyond how bright the final image looks, too. Almost everything after exposure in the pipeline is derived from these values, like bloom and depth of field (when physically based). If the exposure is off, those effects are off with them.
The calculation
The core relationship converts between EV100 and scene luminance using a calibration constant 𝐾 =12.5 (the standard for a reflected-light meter reading an 18% mid-gray) and an ISO sensitivity of 𝑆 =100.
Luminance from a given EV100 value:
And the inverse, deriving EV100 from a known luminance:
Note that 𝐾 =12.5 is a calibration constant, not an EV value. It is what ties the math back to a physically grounded baseline: a meter calibrated this way renders a mid-gray surface as mid-gray.
Scaling between EV values
Once I understood how to measure EV, I experimented with scaling lighting from one EV to another, for example compensating from EV12 to EV16. This turns out to be a straightforward exposure multiplication:
Here 𝐸𝑉𝐴 is the source and 𝐸𝑉𝐵 is the target. Each stop doubles or halves the exposure, so the difference in stops gives you the exact multiplier.
Auto-exposure
Knowing how to calculate exposure opens the door to auto-exposure, which keeps the result from ending up too bright or too dark. Given the average scene luminance 𝐿𝑎𝑣𝑔, the target EV can be derived the same way:
I extended the experiment by introducing a range and an offset. This gives a broader falloff instead of a very strict implementation, which feels more natural.
Building the Desmos visualizer
With all of this in hand, I built my own scene in Desmos to see how the pieces fit together. Moving the EV around and watching luminance respond made the math click in a way the formulas alone never did.
I used 𝑇 as the target EV value and added a smoothstep to interpolate between the measured and the target EV. That way I can always rescale all of my light values to match.
The graph shows three curves. 𝑇 is the target EV value, the red curve 𝐸 is the measured EV value, and the blue curve is the difference in EV between the measured and the target value. By converting that difference into a multiplication, I can effectively compensate the overall exposure of the scene.
I could expand on this by visualizing the min and max offset of the EV value, but I wanted to focus on this part of the equations first. In the end it is only a visualizer of the pure implementation, nothing more.
Takeaway and what's next
Keep in mind that all of these tests use a single value. A real image contains a wide range of luminance, so auto-exposure first averages the luminance across the whole frame and derives one overall EV from that average.
EV100 gave me one shared reference for every light in a scene. Anchor the key light with Sunny 16, convert with a single multiplier, and the rest follows from the same physics. Building the Desmos visualizer turned that from formulas I had read into something I could play with.
It is still a rough tool, and the way exposure is handled has moved on since Lagarde and de Rousiers published "Moving Frostbite to PBR". Next would be for me to also implement it in the engine, to see how this would hold up with real-time content. If you only take one thing from this post: pick your EV first, then set your lights against it, instead of adjusting by eye until it looks right.
© 2026 Stefan Groenewoud - All views are my own, not those of my employer.







