EndlesslyFlowering / ReShade_HDR_shaders

ReShade shaders focused on HDR analysis, (post) processing and (inverse) tone mapping.
GNU General Public License v3.0
172 stars 5 forks source link

sdr_trc_fix: #19

Closed dylanraga closed 4 months ago

dylanraga commented 4 months ago
- compute normalized value so that blacks are not raised by bt1886
- apply bt1886 eotf at input signal instead of its inverse at regamma

Currently, raising the BT.1886 black point also raises the black luminance on regamma. Normalizing the luminance fixes this. This way, the curve will look correct when viewed on a monitor with a non-zero black level.

Also, the BT.1886 eotf can be applied to only the input signal instead, and normally re-gamma'd rather than having two separate functions.

EndlesslyFlowering commented 4 months ago

Yeah the BT.1886 implementation was a bad idea. I was trying to adjust what BT.1886 did to other gamma targets. Also you are right applying it on output is wrong too.

I have rewritten it to work as described in the ITU Recommendation. And it works for both for power gamma and sRGB: 6cdc04968efa1dcb0b76e8d6f1973e3f20e706a0

Let me know what you think :)

dylanraga commented 4 months ago

Looks almost good here! The default option being switched is also a good touch. Just need to normalize the BT1886 value so that black luminance isn't raised,

ie

  float3 L_norm = (L - BT1886_TARGET_BLACKPOINT) / (BT1886_TARGET_WHITEPOINT - BT1886_TARGET_BLACKPOINT);

  return L_norm;

otherwise black levels are lifted on monitors with non-zero black luminance.

EndlesslyFlowering commented 4 months ago

Looks almost good here! The default option being switched is also a good touch. Just need to normalize the BT1886 value so that black luminance isn't raised,

ie

  float3 L_norm = (L - BT1886_TARGET_BLACKPOINT) / (BT1886_TARGET_WHITEPOINT - BT1886_TARGET_BLACKPOINT);

  return L_norm;

otherwise black levels are lifted on monitors with non-zero black luminance.

Uhh that is the whole point of BT.1886 that the black level will be raised to whatever the display is capable of. So if the black point of a display is 0.001 nits you want black (0) raised to 0.001 so that content black matches display black. I know that it doesn't look that great but that's just how BT.1886 works. It affects the whole curve.

Alternatively I could implement the black point adjustment from the BT.2390/BT.2408 EETF. That is what I use in my shader hdr_black_floor_fix: https://github.com/EndlesslyFlowering/ReShade_HDR_shaders/blob/6cdc04968efa1dcb0b76e8d6f1973e3f20e706a0/Shaders/lilium__include/hdr_black_floor_fix.fxh#L207-L224

dylanraga commented 4 months ago

The point of BT.1886 is to create a tailored Gamma 2.4-like curve on a display with a non-zero black level. For example, let's imagine a typical IPS display with a white level of 100 nits and a black level of 0.1 nits (1000:1 contrast).

When outputting the current non-normalized BT.1886 fitted curve on this display, then black (#000000) is no longer 0.1 nits, but ~0.2 nits because the shader black point is being added on top of the display's existing black point. Right now, the shader models what the BT.1886 curve would look like for a certain white/black level, if viewed on a reference OLED. I'm assuming you want this shader to output the correct curve when viewed on the actual display for which the shader white-level and black-level are specified.

Perhaps add a toggle for “black point compensation”.

EndlesslyFlowering commented 4 months ago

The point of BT.1886 is to create a tailored Gamma 2.4-like curve on a display with a non-zero black level. For example, let's imagine a typical IPS display with a white level of 100 nits and a black level of 0.1 nits (1000:1 contrast).

When outputting the current non-normalized BT.1886 fitted curve on this display, then black (#000000) is no longer 0.1 nits, but ~0.2 nits because the shader black point is being added on top of the display's existing black point. Right now, the shader models what the BT.1886 curve would look like for a certain white/black level, if viewed on a reference OLED. I'm assuming you want this shader to output the correct curve when viewed on the actual display for which the shader white-level and black-level are specified.

Perhaps add a toggle for “black point compensation”.

you are right

EndlesslyFlowering commented 4 months ago

implemented here: d5a088041befdb1f24076d68ccad09e299eb26e3