Just give me local tonemapping
In my last post I went on about how a global tone curve only fakes half of what your eyes do. It squeezes the huge range of a scene down into the sliver a display can show, but it skips the part where your eyes adapt locally, lifting the shadows and taming the highlights region by region. I ended that post by complaining that the tools to put that local part back, the ones photographers have in Lightroom, basically don't exist in any 3D software.
So let's talk about why, and why I think that's dumb.
Loyal to the sensor or loyal to the eye?
Global tonemapping is honest in a very specific way. It's one curve, it's monotonic, and the same input brightness always maps to the same output brightness no matter where it sits in the frame. Nothing moves around. The radiometric relationships you worked so hard to get right are preserved exactly. A purist looks at that and says "this is correct."
But correct to what? A global curve is faithful to what a camera produces. It is not faithful to a human eye, because your eye does not apply one curve to the whole scene. Your retina is running local adaptation all day long, which is the entire reason you can stand in a dim room and still see detail in the bright window. If the goal is to reproduce how a person standing in that room would actually perceive it, then local tonemapping isn't the cheat. It's the more honest answer.
So when someone insists global is the "real" one, what they're really defending is fidelity to the sensor, not fidelity to perception.
Why render engines pick the sensor
And to be fair, render engines have a good reason to pick the sensor. They grew up next to film and VFX, where the renderer is one stage in a pipeline. You need scene linear data flowing out the back so the compositor can integrate CG into live action plates, match real camera footage, and grade everything together later. In that world a monotonic curve the basis of a predictable and essential workflow, not a limitation. A pixel is too bright, you can reason straight back to the light or the material that caused it, because nothing in the image moved relative to anything else. Local tonemapping breaks that. It decouples cause and effect across the frame, and for a film pipeline that's a big fat no. So why implement it?
I get it. If your renderer's job is to feed a comp, mimicking a camera is the right call.
But archviz is not film
Here's where it falls apart. The guy doing architectural visualization is not feeding a compositor. He's trying to sell a nice render to a property developer. The whole job is making someone feel like they're standing in that kitchen, and the look he's chasing, that clean real estate photo look, is literally only achievable with local adjustments. It's the same reason a phone shooting a real kitchen does a pile of automatic local HDR before it ever hands you the photo. There's no comp downstream that needs the radiometry intact. The argument for keeping things monotonic just doesn't apply to him.
He's just expected to waste his time, putting image into lightroom or acr, doing the same few adjustments he's always doing
So why does he get told no?
The real reason is sunk cost
I think the actual reason the engineers hate it has nothing to do with film pipelines. It's pride. They spent years getting the radiometric values physically correct, every bounce, every falloff, every material response sitting exactly where the physics says it should. And local tonemapping takes a spatially varying filter and shreds those perfect relationships on purpose. To them it feels like vandalism. They built a beautiful honest number and you want to bolt a thing on the end that lies about it.
I understand the feeling. I just don't think it's a good enough reason to withhold a genuinely useful feature from everyone who isn't doing VFX. Or animation.
And the thing is, it's dead simple
This is what kills me. We're not talking about some research grade algorithm. The base version is almost embarrassingly easy:
- Blur the image with a bilateral filter (or variants on it like a domain transform).
- Subtract that blurred lightness from the original lightness to get a detail layer.
- Recenter the blurred lightness around zero, reduce its contrast, then undo the centering.
- Add the detail layer and the original colors back on top.
- You tonemap the result with the regular global tonemap
That's it. That's a local tonemapper. The bilateral filter does the region finding for you, the contrast reduction on the low frequency layer is the actual tone compression, and reattaching the detail layer means you don't lose any of the crisp stuff. I've got this running in Python at home and it already looks better than any render that's exclusively using a global curve.
Corona, V-Ray, whoever, these are C++ engines with people who eat bilateral filters for breakfast. This is a one day feature for them, it runs plenty fast at that level, and I'm completely sure they'd do a cleaner job than my little Python toy. The math is not the obstacle. The willingness is.
So this is me asking nicely. Just give me the slider.