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: fix input->output transform #18

Closed dylanraga closed 4 months ago

dylanraga commented 4 months ago

The sdr_trc_fix effect was not working as intended. It's expected to transform an input curve, such as piecewise sRGB, to be rendered as another curve, such as gamma 2.2.

The previous implementation decoded display RGB to linear using input curve EOTF, then re-encoded with the target curve inverse EOTF. This transformation produces an incorrect result.

Instead, display RGB needs to be decoded to linear using target curve EOTF, then re-encoded with input curve inverse EOTF.

Also fixed BT1886 relative-black transform.

EndlesslyFlowering commented 4 months ago

nooooooooo I haven't touched that shader in soo long 🥲

EndlesslyFlowering commented 4 months ago

The sdr_trc_fix effect was not working as intended. It's expected to transform an input curve, such as piecewise sRGB, to be rendered as another curve, such as gamma 2.2.

The previous implementation decoded display RGB to linear using input curve EOTF, then re-encoded with the target curve inverse EOTF. This transformation produces an incorrect result.

Instead, display RGB needs to be decoded to linear using target curve EOTF, then re-encoded with input curve inverse EOTF.

Also fixed BT1886 relative-black transform.

Not quite sure what you mean. Are you sure you didn't get the naming mixed up? Input is what EOTF/gamma the input is encoded with. Target is what your display's EOTF/gamma is.

BT.1886 is probably broken though.

BT.1886 is meant as an output transform to adjust the black point only. Guess that is not really clear.

dylanraga commented 4 months ago

As a quick test, when input_trc == output_trc, you should expect there to be zero difference, ie pixel rgb passthrough. With the current shader, this is not the case and the result is different. This is because the current order of the regamma is inversed a bug on line 118.

The default setup is an input_trc of sRGB and a target_trc of gamma 2.2, and you would expect this to transform the curve in a game such that it renders as gamma 2.2 when it appears to be outputting sRGB, such as when you're using Windows HDR. Currently, this configuration washes out the image even further than sRGB. I've fixed and tested this in the provided commits.

BT1886 was also buggy, and right now my changes lifts the black level to the selected black point w.r.t BT1886 EOTF. This needs to get mapped down so that L=black_point is mapped to an encoded value of zero.

dylanraga commented 4 months ago

Here's a comparison of the feature disabled (1) and enabled (2). When the shader is activated, the image becomes washed out, instead of having the intended appearance of looking like the target TRC. Images meant to be viewed with sRGB EOTF.

poe_sdr_trc_fix_disabled poe_sdr_trc_fix_enabled
dylanraga commented 4 months ago

Actually, given this description:

Input is what EOTF/gamma the input is encoded with. Target is what your display's EOTF/gamma is.

The issue is line 118, which should be fixedGamma = Csp::Trc::LinearTo::Srgb(fixedGamma);. Then, to achieve sRGB->Gamma transformation, input_trc should be gamma 2.2 and output_trc should be sRGB. However this now has no effect with BT1886.

My understanding was that input_trc is the curve the game was intended to be encoded with, usually sRGB. And target_trc was the target "look" of the game when output to your monitor, which makes more sense to me.

EndlesslyFlowering commented 4 months ago

Actually, given this description:

Input is what EOTF/gamma the input is encoded with. Target is what your display's EOTF/gamma is.

The issue is line 118, which should be fixedGamma = Csp::Trc::LinearTo::Srgb(fixedGamma);. Then, to achieve sRGB->Gamma transformation, input_trc should be gamma 2.2 and output_trc should be sRGB. However this now has no effect with BT1886.

My understanding was that input_trc is the curve the game was intended to be encoded with, usually sRGB. And target_trc was the target "look" of the game when output to your monitor, which makes more sense to me.

omg line 118 🥲 how did I not see that yeah fixing that make passthrough work on my end

I adopted the target-trc naming from mpv

about BT.1886 not working: I guess I could change it to use sRGB too

EndlesslyFlowering commented 4 months ago

I fixed the issue and made BT.1886 functional for sRGB output also added you as co-author :)

752bf6949fdb4d8110e21663c4470ce673e600f6