Tom94 / tev

High dynamic range (HDR) image viewer for graphics people
BSD 3-Clause "New" or "Revised" License
1.02k stars 86 forks source link

Pixel intensity overflow in HDR mode #166

Closed wjakob closed 1 year ago

wjakob commented 2 years ago

Hi Thomas,

I noticed that the new HDR view of 'tev' encounters some kind of overflow/non-monotonicity when cranking up the exposure and bright pixels (EXR value ~ 5) are visible. This happens in the green/red visualization of signed images -- try opening the attached EXR file on a Mac in HDR mode and increase the exposure -- suddenly, many of the pixel flip from red to black.

I tried to capture a screengrab, but curiously the problem isn't visible there. It's possible that there is some kind of max intensity value for floating point buffers (e.g. 64K) that is being reached.

Thanks, Wenzel

bwd.exr.zip

Tom94 commented 2 years ago

Hi Wenzel, I can't reproduce the issue on my macbook, unfortunately -- the pixels just keep getting brighter and eventually saturate to white. The attached screen recording is representative of what I see.

https://user-images.githubusercontent.com/4923655/148978423-5f08c2fc-2063-4c63-9a00-ffb54e6e6696.mov

You can also see flickering that I've started to experience since switching my M1 Max that I mentioned recently. Seems at first like a separate issue (no overflow behavior), but who knows -- might be related in the end.

Tom94 commented 2 years ago

Before I start digging deeper into tev, could you check whether the same overflow occurs when cranking the brightness in one of the nanogui samples? Thanks!

wjakob commented 2 years ago

It's on a Pro Display XDR in my case, but with the not-quite-latest macOS version (which may be relevant here, Apple has been doing a lot of work on HDR support in the OS). I plan to give this another try with Monterey when I receive my M1 machine in February. (Busy with the SIGGRAPH deadline until then, too .. ;-))

Tom94 commented 2 years ago

Heh, no hurry (and a successful crunch!).

Another thought: if the overflow indeed happens at reasonably large values (e.g. an eye-searing 64k), I'm happy to add clamping in any case -- just let me know if you find a specific value.

wjakob commented 2 years ago

The magic value seems to be 64, and this fixes it:

diff --git a/src/UberShader.cpp b/src/UberShader.cpp
index 91d9a8a..68b4d88 100644
--- a/src/UberShader.cpp
+++ b/src/UberShader.cpp
@@ -355,9 +355,8 @@ UberShader::UberShader(RenderPass* renderPass) {
                         ),
                         1.0f
                     );
-                    if (clipToLdr) {
-                        color.rgb = clamp(color.rgb, 0.0f, 1.0f);
-                    }
+                    color.rgb = clamp(color.rgb, clipToLdr ? 0.f : -64.f,
+                                                 clipToLdr ? 1.f :  64.f);
                     return color;
                 }

@@ -377,9 +376,8 @@ UberShader::UberShader(RenderPass* renderPass) {
                     ),
                     1.0f
                 );
-                if (clipToLdr) {
-                    color.rgb = clamp(color.rgb, 0.0f, 1.0f);
-                }
+                color.rgb = clamp(color.rgb, clipToLdr ? 0.f : -64.f,
+                                             clipToLdr ? 1.f :  64.f);
                 return color;
             })";
 #endif
wjakob commented 2 years ago

https://user-images.githubusercontent.com/1203629/148985978-3c13dd65-dbab-466a-801f-d1cf1aaae47d.MOV

Here is that that looks like by the way.

Tom94 commented 2 years ago

Thanks for checking! 64 seems rather low, to be honest, but still a factor of ~4 above what my highest dynamic range display (the laptop) can output. So... I doubt the extra clamp affects anyone as of now. :)