Tom94 / tev

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

OpenEXR alpha is premultiplied #87

Closed dvicini closed 4 years ago

dvicini commented 4 years ago

Hi Thomas,

It seems that tev doesn't handle the alpha channel of OpenEXR images quite right. By convention, OpenEXR images use "premultiplied alpha" (see page 21 in https://www.openexr.com/documentation/TechnicalIntroduction.pdf). That means that the color values stored in the OpenEXR file are already multiplied by alpha.

From what I have seen, tev does not account for this (please correct me if I missed something). This leads to behavior which isn't consistent with standard tools (e.g. Adobe Photoshop or MacOS Preview). I uploaded two example EXR images here: https://www.dropbox.com/sh/5ngueg2vf6dwvho/AAAoMuo2d0jqO0Y-XJ_AIvzVa?dl=0

The premultiplied image looks wrong in tev, but correct in the other two programs. The problem is most likely easily fixed by dividing the RGB values by alpha when loading the image (and doing nothing if alpha == 0)

Cheers, Delio

Tom94 commented 4 years ago

That's actually amazing, thanks for letting me know!

Now I feel stupid for not realizing earlier why the heck all the transparent sample images had weird-looking dark halos. Fix to be merged within the hour. :)

dvicini commented 4 years ago

Awesome! Thanks

sboukortt commented 4 years ago

Thanks for fixing this! Much appreciated.

However, the current fix doesn’t work for images that have alpha=0 associated with non-zero pixel values, for example the flame and the reflection in: https://github.com/AcademySoftwareFoundation/openexr-images/blob/master/ScanLines/CandleGlass.exr which become invisible in tev (pfsv from pfstools shows them).

Perhaps a more general fix would be to keep the image in premultiplied alpha, and perform the blending accordingly when rendering. Would that be feasible without too much trouble?

Tom94 commented 4 years ago

Hi Sami, thanks for pointing this out! I initially (naïvely) assumed, that alpha=0 with non-zero pixel values never happens in practice and left it at that.

Your comment actually made me realize that premultiplied alpha as an internal representation makes a whole lot of sense for tev in many other ways than just transparent emissive objects: premultiplied alpha corresponds to light emitted by a pixel and therefore all color comparisons, statistics, histograms, etc. should be based on premultiplied alpha as opposed to straight colors.

So... that's now changed. And the 0-alpha has been fixed as a side-effect. :)

(Also, alpha-blending is now correctly performed in linear color space as opposed to after tonemapping. I don't know what I was thinking back when I implemented that.)

sboukortt commented 4 years ago

Wow, that was quick :D Many thanks!