From bf9452433cac5049c74ebaf7bbbcb11e2853c6e5 Mon Sep 17 00:00:00 2001 From: llyyr Date: Fri, 5 Dec 2025 02:32:37 +0530 Subject: [PATCH] render/vulkan: normalize luminance range in bt.1886 formula BT.1886 is different from other EOTFs in that the spec says that offset b must be in electrical domain, so use the assumed display environment from the specification as Lmin and Lmax then normalize bt.1886 to produce optical luminance L in [0, 1]. See discussion at https://gitlab.freedesktop.org/pq/color-and-hdr/-/merge_requests/63#note_3090016 --- render/vulkan/shaders/output.frag | 9 ++++++--- render/vulkan/shaders/texture.frag | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/render/vulkan/shaders/output.frag b/render/vulkan/shaders/output.frag index 5b952fcff..0a8d9b855 100644 --- a/render/vulkan/shaders/output.frag +++ b/render/vulkan/shaders/output.frag @@ -49,11 +49,14 @@ vec3 linear_color_to_pq(vec3 color) { } vec3 linear_color_to_bt1886(vec3 color) { - float lb = pow(0.0001, 1.0 / 2.4); - float lw = pow(1.0, 1.0 / 2.4); + float Lmin = 0.01; + float Lmax = 100.0; + float lb = pow(Lmin, 1.0 / 2.4); + float lw = pow(Lmax, 1.0 / 2.4); float a = pow(lw - lb, 2.4); float b = lb / (lw - lb); - return pow(color / a, vec3(1.0 / 2.4)) - vec3(b); + vec3 L = color * (Lmax - Lmin) + vec3(Lmin); + return pow(L / a, vec3(1.0 / 2.4)) - vec3(b); } void main() { diff --git a/render/vulkan/shaders/texture.frag b/render/vulkan/shaders/texture.frag index 57d2d049c..3ec974235 100644 --- a/render/vulkan/shaders/texture.frag +++ b/render/vulkan/shaders/texture.frag @@ -47,11 +47,14 @@ vec3 pq_color_to_linear(vec3 color) { } vec3 bt1886_color_to_linear(vec3 color) { - float lb = pow(0.0001, 1.0 / 2.4); - float lw = pow(1.0, 1.0 / 2.4); + float Lmin = 0.01; + float Lmax = 100.0; + float lb = pow(Lmin, 1.0 / 2.4); + float lw = pow(Lmax, 1.0 / 2.4); float a = pow(lw - lb, 2.4); float b = lb / (lw - lb); - return a * pow(color + vec3(b), vec3(2.4)); + vec3 L = a * pow(color + vec3(b), vec3(2.4)); + return (L - Lmin) / (Lmax - Lmin); } void main() {