renderer/cm: higher-quality tonemapping (#12204)
This commit is contained in:
parent
ca99e8228c
commit
532ca053d6
5 changed files with 53 additions and 25 deletions
|
|
@ -971,6 +971,7 @@ static void getCMShaderUniforms(SShader& shader) {
|
|||
shader.uniformLocations[SHADER_DST_TF_RANGE] = glGetUniformLocation(shader.program, "dstTFRange");
|
||||
shader.uniformLocations[SHADER_TARGET_PRIMARIES] = glGetUniformLocation(shader.program, "targetPrimaries");
|
||||
shader.uniformLocations[SHADER_MAX_LUMINANCE] = glGetUniformLocation(shader.program, "maxLuminance");
|
||||
shader.uniformLocations[SHADER_SRC_REF_LUMINANCE] = glGetUniformLocation(shader.program, "srcRefLuminance");
|
||||
shader.uniformLocations[SHADER_DST_MAX_LUMINANCE] = glGetUniformLocation(shader.program, "dstMaxLuminance");
|
||||
shader.uniformLocations[SHADER_DST_REF_LUMINANCE] = glGetUniformLocation(shader.program, "dstRefLuminance");
|
||||
shader.uniformLocations[SHADER_SDR_SATURATION] = glGetUniformLocation(shader.program, "sdrSaturation");
|
||||
|
|
@ -1560,6 +1561,14 @@ static bool isSDR2HDR(const NColorManagement::SImageDescription& imageDescriptio
|
|||
targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_HLG);
|
||||
}
|
||||
|
||||
static bool isHDR2SDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) {
|
||||
// might be too strict
|
||||
return (imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ||
|
||||
imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_HLG) &&
|
||||
(targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB ||
|
||||
targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SImageDescription& imageDescription,
|
||||
const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) {
|
||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
||||
|
|
@ -1585,16 +1594,22 @@ void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SI
|
|||
shader.setUniformMatrix4x2fv(SHADER_TARGET_PRIMARIES, 1, false, glTargetPrimaries);
|
||||
|
||||
const bool needsSDRmod = modifySDR && isSDR2HDR(imageDescription, targetImageDescription);
|
||||
const bool needsHDRmod = !needsSDRmod && isHDR2SDR(imageDescription, targetImageDescription);
|
||||
|
||||
shader.setUniformFloat2(SHADER_SRC_TF_RANGE, imageDescription.getTFMinLuminance(needsSDRmod ? sdrMinLuminance : -1),
|
||||
imageDescription.getTFMaxLuminance(needsSDRmod ? sdrMaxLuminance : -1));
|
||||
shader.setUniformFloat2(SHADER_DST_TF_RANGE, targetImageDescription.getTFMinLuminance(needsSDRmod ? sdrMinLuminance : -1),
|
||||
targetImageDescription.getTFMaxLuminance(needsSDRmod ? sdrMaxLuminance : -1));
|
||||
|
||||
const float maxLuminance = imageDescription.luminances.max > 0 ? imageDescription.luminances.max : imageDescription.luminances.reference;
|
||||
shader.setUniformFloat(SHADER_MAX_LUMINANCE, maxLuminance * targetImageDescription.luminances.reference / imageDescription.luminances.reference);
|
||||
shader.setUniformFloat(SHADER_SRC_REF_LUMINANCE, imageDescription.getTFRefLuminance(-1));
|
||||
shader.setUniformFloat(SHADER_DST_REF_LUMINANCE, targetImageDescription.getTFRefLuminance(-1));
|
||||
|
||||
const float maxLuminance =
|
||||
needsHDRmod ? imageDescription.getTFMaxLuminance(-1) : (imageDescription.luminances.max > 0 ? imageDescription.luminances.max : imageDescription.luminances.reference);
|
||||
shader.setUniformFloat(SHADER_MAX_LUMINANCE,
|
||||
maxLuminance * targetImageDescription.luminances.reference /
|
||||
(needsHDRmod ? imageDescription.getTFRefLuminance(-1) : imageDescription.luminances.reference));
|
||||
shader.setUniformFloat(SHADER_DST_MAX_LUMINANCE, targetImageDescription.luminances.max > 0 ? targetImageDescription.luminances.max : 10000);
|
||||
shader.setUniformFloat(SHADER_DST_REF_LUMINANCE, targetImageDescription.luminances.reference);
|
||||
shader.setUniformFloat(SHADER_SDR_SATURATION, needsSDRmod && m_renderData.pMonitor->m_sdrSaturation > 0 ? m_renderData.pMonitor->m_sdrSaturation : 1.0f);
|
||||
shader.setUniformFloat(SHADER_SDR_BRIGHTNESS, needsSDRmod && m_renderData.pMonitor->m_sdrBrightness > 0 ? m_renderData.pMonitor->m_sdrBrightness : 1.0f);
|
||||
const auto cacheKey = std::make_pair(imageDescription.getId(), targetImageDescription.getId());
|
||||
|
|
@ -1710,11 +1725,8 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
|
|||
if (shader == &m_shaders->m_shCM) {
|
||||
shader->setUniformInt(SHADER_TEX_TYPE, texType);
|
||||
if (data.cmBackToSRGB) {
|
||||
// revert luma changes to avoid black screenshots.
|
||||
// this will likely not be 1:1, and might cause screenshots to be too bright, but it's better than pitch black.
|
||||
imageDescription.luminances = {};
|
||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
||||
auto chosenSdrEotf = *PSDREOTF > 0 ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB;
|
||||
static auto PSDREOTF = CConfigValue<Hyprlang::INT>("render:cm_sdr_eotf");
|
||||
auto chosenSdrEotf = *PSDREOTF > 0 ? NColorManagement::CM_TRANSFER_FUNCTION_GAMMA22 : NColorManagement::CM_TRANSFER_FUNCTION_SRGB;
|
||||
passCMUniforms(*shader, imageDescription, NColorManagement::SImageDescription{.transferFunction = chosenSdrEotf}, true, -1, -1);
|
||||
} else
|
||||
passCMUniforms(*shader, imageDescription);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue