mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-07-25 17:21:54 -07:00
renderer: implement wp-color-management-v1 transfer functions (#11084)
This commit is contained in:
@@ -44,16 +44,13 @@ CColorManager::CColorManager(SP<CWpColorManagerV1> resource) : m_resource(resour
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG);
|
||||
|
||||
if (PROTO::colorManagement->m_debug) {
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST240);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_100);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_316);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_XVYCC);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_SRGB);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST428);
|
||||
}
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST240);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_100);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_316);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_XVYCC);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_SRGB);
|
||||
m_resource->sendSupportedTfNamed(WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST428);
|
||||
|
||||
m_resource->sendSupportedIntent(WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
|
||||
if (PROTO::colorManagement->m_debug) {
|
||||
@@ -549,6 +546,13 @@ CColorManagementParametricCreator::CColorManagementParametricCreator(SP<CWpImage
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA22: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_GAMMA28: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_HLG: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_BT1886: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST240: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_100: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_LOG_316: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_XVYCC: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_SRGB: break;
|
||||
case WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST428: break;
|
||||
default: r->error(WP_IMAGE_DESCRIPTION_CREATOR_PARAMS_V1_ERROR_INVALID_TF, "Unsupported transfer function"); return;
|
||||
}
|
||||
|
||||
|
@@ -58,6 +58,14 @@ CXXColorManager::CXXColorManager(SP<CXxColorManagerV4> resource_) : m_resource(r
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB);
|
||||
m_resource->sendSupportedTfNamed(XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428);
|
||||
|
||||
m_resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_PERCEPTUAL);
|
||||
// resource->sendSupportedIntent(XX_COLOR_MANAGER_V4_RENDER_INTENT_RELATIVE);
|
||||
@@ -405,7 +413,15 @@ CXXColorManagementParametricCreator::CXXColorManagementParametricCreator(SP<CXxI
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_HLG:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_SRGB:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST2084_PQ:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR: break;
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LINEAR:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT709:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_BT1361:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST240:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_100:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_LOG_316:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_XVYCC:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_EXT_SRGB:
|
||||
case XX_COLOR_MANAGER_V4_TRANSFER_FUNCTION_ST428: break;
|
||||
default: r->error(XX_IMAGE_DESCRIPTION_CREATOR_PARAMS_V4_ERROR_INVALID_TF, "Unsupported transfer function"); return;
|
||||
}
|
||||
|
||||
|
@@ -25,12 +25,23 @@ uniform mat3 convertMatrix;
|
||||
|
||||
// sRGB constants
|
||||
#define SRGB_POW 2.4
|
||||
#define SRGB_INV_POW (1.0 / SRGB_POW)
|
||||
#define SRGB_D_CUT 0.04045
|
||||
#define SRGB_E_CUT 0.0031308
|
||||
#define SRGB_LO 12.92
|
||||
#define SRGB_HI 1.055
|
||||
#define SRGB_HI_ADD 0.055
|
||||
#define SRGB_CUT 0.0031308
|
||||
#define SRGB_SCALE 12.92
|
||||
#define SRGB_ALPHA 1.055
|
||||
|
||||
#define BT1886_POW (1.0 / 0.45)
|
||||
#define BT1886_CUT 0.018053968510807
|
||||
#define BT1886_SCALE 4.5
|
||||
#define BT1886_ALPHA (1.0 + 5.5 * BT1886_CUT)
|
||||
|
||||
// See http://car.france3.mars.free.fr/HD/INA-%2026%20jan%2006/SMPTE%20normes%20et%20confs/s240m.pdf
|
||||
#define ST240_POW (1.0 / 0.45)
|
||||
#define ST240_CUT 0.0228
|
||||
#define ST240_SCALE 4.0
|
||||
#define ST240_ALPHA 1.1115
|
||||
|
||||
#define ST428_POW 2.6
|
||||
#define ST428_SCALE (52.37 / 48.0)
|
||||
|
||||
// PQ constants
|
||||
#define PQ_M1 0.1593017578125
|
||||
@@ -43,7 +54,7 @@ uniform mat3 convertMatrix;
|
||||
|
||||
// HLG constants
|
||||
#define HLG_D_CUT (1.0 / 12.0)
|
||||
#define HLG_E_CUT (sqrt(3.0) * pow(HLG_D_CUT, 0.5))
|
||||
#define HLG_E_CUT 0.5
|
||||
#define HLG_A 0.17883277
|
||||
#define HLG_B 0.28466892
|
||||
#define HLG_C 0.55991073
|
||||
@@ -59,7 +70,7 @@ uniform mat3 convertMatrix;
|
||||
vec3 xy2xyz(vec2 xy) {
|
||||
if (xy.y == 0.0)
|
||||
return vec3(0.0, 0.0, 0.0);
|
||||
|
||||
|
||||
return vec3(xy.x / xy.y, 1.0, (1.0 - xy.x - xy.y) / xy.y);
|
||||
}
|
||||
|
||||
@@ -71,43 +82,131 @@ vec4 saturate(vec4 color, mat3 primaries, float saturation) {
|
||||
return vec4(mix(vec3(Y), color.rgb, saturation), color[3]);
|
||||
}
|
||||
|
||||
vec3 toLinearRGB(vec3 color, int tf) {
|
||||
if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR)
|
||||
return color;
|
||||
|
||||
bvec3 isLow;
|
||||
vec3 lo;
|
||||
vec3 hi;
|
||||
switch (tf) {
|
||||
case CM_TRANSFER_FUNCTION_ST2084_PQ:
|
||||
vec3 E = pow(clamp(color.rgb, vec3(0.0), vec3(1.0)), vec3(PQ_INV_M2));
|
||||
return pow(
|
||||
(max(E - PQ_C1, vec3(0.0))) / (PQ_C2 - PQ_C3 * E),
|
||||
vec3(PQ_INV_M1)
|
||||
);
|
||||
case CM_TRANSFER_FUNCTION_GAMMA22:
|
||||
return pow(max(color.rgb, vec3(0.0)), vec3(2.2));
|
||||
case CM_TRANSFER_FUNCTION_GAMMA28:
|
||||
return pow(max(color.rgb, vec3(0.0)), vec3(2.8));
|
||||
case CM_TRANSFER_FUNCTION_HLG:
|
||||
isLow = lessThanEqual(color.rgb, vec3(HLG_D_CUT));
|
||||
lo = sqrt(3.0) * pow(color.rgb, vec3(0.5));
|
||||
hi = HLG_A * log(12.0 * color.rgb - HLG_B) + HLG_C;
|
||||
return mix(hi, lo, isLow);
|
||||
case CM_TRANSFER_FUNCTION_BT1886:
|
||||
case CM_TRANSFER_FUNCTION_ST240:
|
||||
case CM_TRANSFER_FUNCTION_LOG_100:
|
||||
case CM_TRANSFER_FUNCTION_LOG_316:
|
||||
case CM_TRANSFER_FUNCTION_XVYCC:
|
||||
case CM_TRANSFER_FUNCTION_EXT_SRGB:
|
||||
case CM_TRANSFER_FUNCTION_ST428:
|
||||
// The primary source for these transfer functions is https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.1361-0-199802-W!!PDF-E.pdf
|
||||
vec3 tfInvPQ(vec3 color) {
|
||||
vec3 E = pow(clamp(color.rgb, vec3(0.0), vec3(1.0)), vec3(PQ_INV_M2));
|
||||
return pow(
|
||||
(max(E - PQ_C1, vec3(0.0))) / (PQ_C2 - PQ_C3 * E),
|
||||
vec3(PQ_INV_M1)
|
||||
);
|
||||
}
|
||||
|
||||
vec3 tfInvHLG(vec3 color) {
|
||||
bvec3 isLow = lessThanEqual(color.rgb, vec3(HLG_E_CUT));
|
||||
vec3 lo = color.rgb * color.rgb / 3.0;
|
||||
vec3 hi = (exp((color.rgb - HLG_C) / HLG_A) + HLG_B) / 12.0;
|
||||
return mix(hi, lo, isLow);
|
||||
}
|
||||
|
||||
// Many transfer functions (including sRGB) follow the same pattern: a linear
|
||||
// segment for small values and a power function for larger values. The
|
||||
// following function implements this pattern from which sRGB, BT.1886, and
|
||||
// others can be derived by plugging in the right constants.
|
||||
vec3 tfInvLinPow(vec3 color, float gamma, float thres, float scale, float alpha) {
|
||||
bvec3 isLow = lessThanEqual(color.rgb, vec3(thres * scale));
|
||||
vec3 lo = color.rgb / scale;
|
||||
vec3 hi = pow((color.rgb + alpha - 1.0) / alpha, vec3(gamma));
|
||||
return mix(hi, lo, isLow);
|
||||
}
|
||||
|
||||
vec3 tfInvSRGB(vec3 color) {
|
||||
return tfInvLinPow(color, SRGB_POW, SRGB_CUT, SRGB_SCALE, SRGB_ALPHA);
|
||||
}
|
||||
|
||||
vec3 tfInvExtSRGB(vec3 color) {
|
||||
// EXT sRGB is the sRGB transfer function mirrored around 0.
|
||||
return sign(color) * tfInvSRGB(abs(color));
|
||||
}
|
||||
|
||||
vec3 tfInvBT1886(vec3 color) {
|
||||
return tfInvLinPow(color, BT1886_POW, BT1886_CUT, BT1886_SCALE, BT1886_ALPHA);
|
||||
}
|
||||
|
||||
vec3 tfInvXVYCC(vec3 color) {
|
||||
// The inverse transfer function for XVYCC is the BT1886 transfer function mirrored around 0,
|
||||
// same as what EXT sRGB is to sRGB.
|
||||
return sign(color) * tfInvBT1886(abs(color));
|
||||
}
|
||||
|
||||
vec3 tfInvST240(vec3 color) {
|
||||
return tfInvLinPow(color, ST240_POW, ST240_CUT, ST240_SCALE, ST240_ALPHA);
|
||||
}
|
||||
|
||||
// Forward transfer functions corresponding to the inverse functions above.
|
||||
vec3 tfPQ(vec3 color) {
|
||||
vec3 E = pow(clamp(color.rgb, vec3(0.0), vec3(1.0)), vec3(PQ_M1));
|
||||
return pow(
|
||||
(vec3(PQ_C1) + PQ_C2 * E) / (vec3(1.0) + PQ_C3 * E),
|
||||
vec3(PQ_M2)
|
||||
);
|
||||
}
|
||||
|
||||
vec3 tfHLG(vec3 color) {
|
||||
bvec3 isLow = lessThanEqual(color.rgb, vec3(HLG_D_CUT));
|
||||
vec3 lo = sqrt(max(color.rgb, vec3(0.0)) * 3.0);
|
||||
vec3 hi = HLG_A * log(max(12.0 * color.rgb - HLG_B, vec3(0.0001))) + HLG_C;
|
||||
return mix(hi, lo, isLow);
|
||||
}
|
||||
|
||||
vec3 tfLinPow(vec3 color, float gamma, float thres, float scale, float alpha) {
|
||||
bvec3 isLow = lessThanEqual(color.rgb, vec3(thres));
|
||||
vec3 lo = color.rgb * scale;
|
||||
vec3 hi = pow(color.rgb, vec3(1.0 / gamma)) * alpha - (alpha - 1.0);
|
||||
return mix(hi, lo, isLow);
|
||||
}
|
||||
|
||||
vec3 tfSRGB(vec3 color) {
|
||||
return tfLinPow(color, SRGB_POW, SRGB_CUT, SRGB_SCALE, SRGB_ALPHA);
|
||||
}
|
||||
|
||||
vec3 tfExtSRGB(vec3 color) {
|
||||
// EXT sRGB is the sRGB transfer function mirrored around 0.
|
||||
return sign(color) * tfSRGB(abs(color));
|
||||
}
|
||||
|
||||
vec3 tfBT1886(vec3 color) {
|
||||
return tfLinPow(color, BT1886_POW, BT1886_CUT, BT1886_SCALE, BT1886_ALPHA);
|
||||
}
|
||||
|
||||
vec3 tfXVYCC(vec3 color) {
|
||||
// The transfer function for XVYCC is the BT1886 transfer function mirrored around 0,
|
||||
// same as what EXT sRGB is to sRGB.
|
||||
return sign(color) * tfBT1886(abs(color));
|
||||
}
|
||||
|
||||
vec3 tfST240(vec3 color) {
|
||||
return tfLinPow(color, ST240_POW, ST240_CUT, ST240_SCALE, ST240_ALPHA);
|
||||
}
|
||||
|
||||
vec3 toLinearRGB(vec3 color, int tf) {
|
||||
switch (tf) {
|
||||
case CM_TRANSFER_FUNCTION_EXT_LINEAR:
|
||||
return color;
|
||||
case CM_TRANSFER_FUNCTION_ST2084_PQ:
|
||||
return tfInvPQ(color);
|
||||
case CM_TRANSFER_FUNCTION_GAMMA22:
|
||||
return pow(max(color, vec3(0.0)), vec3(2.2));
|
||||
case CM_TRANSFER_FUNCTION_GAMMA28:
|
||||
return pow(max(color, vec3(0.0)), vec3(2.8));
|
||||
case CM_TRANSFER_FUNCTION_HLG:
|
||||
return tfInvHLG(color);
|
||||
case CM_TRANSFER_FUNCTION_EXT_SRGB:
|
||||
return tfInvExtSRGB(color);
|
||||
case CM_TRANSFER_FUNCTION_BT1886:
|
||||
return tfInvBT1886(color);
|
||||
case CM_TRANSFER_FUNCTION_ST240:
|
||||
return tfInvST240(color);
|
||||
case CM_TRANSFER_FUNCTION_LOG_100:
|
||||
return mix(exp((color - 1.0) * 2.0 * log(10.0)), vec3(0.0), lessThanEqual(color, vec3(0.0)));
|
||||
case CM_TRANSFER_FUNCTION_LOG_316:
|
||||
return mix(exp((color - 1.0) * 2.5 * log(10.0)), vec3(0.0), lessThanEqual(color, vec3(0.0)));
|
||||
case CM_TRANSFER_FUNCTION_XVYCC:
|
||||
return tfInvXVYCC(color);
|
||||
case CM_TRANSFER_FUNCTION_ST428:
|
||||
return pow(max(color, vec3(0.0)), vec3(ST428_POW)) * ST428_SCALE;
|
||||
case CM_TRANSFER_FUNCTION_SRGB:
|
||||
default:
|
||||
isLow = lessThanEqual(color.rgb, vec3(SRGB_D_CUT));
|
||||
lo = color.rgb / SRGB_LO;
|
||||
hi = pow((color.rgb + SRGB_HI_ADD) / SRGB_HI, vec3(SRGB_POW));
|
||||
return mix(hi, lo, isLow);
|
||||
return tfInvSRGB(color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,50 +226,41 @@ vec4 toNit(vec4 color, vec2 range) {
|
||||
}
|
||||
|
||||
vec3 fromLinearRGB(vec3 color, int tf) {
|
||||
bvec3 isLow;
|
||||
vec3 lo;
|
||||
vec3 hi;
|
||||
|
||||
switch (tf) {
|
||||
case CM_TRANSFER_FUNCTION_EXT_LINEAR:
|
||||
return color;
|
||||
case CM_TRANSFER_FUNCTION_ST2084_PQ:
|
||||
vec3 E = pow(clamp(color.rgb, vec3(0.0), vec3(1.0)), vec3(PQ_M1));
|
||||
return pow(
|
||||
(vec3(PQ_C1) + PQ_C2 * E) / (vec3(1.0) + PQ_C3 * E),
|
||||
vec3(PQ_M2)
|
||||
);
|
||||
break;
|
||||
return tfPQ(color);
|
||||
case CM_TRANSFER_FUNCTION_GAMMA22:
|
||||
return pow(max(color.rgb, vec3(0.0)), vec3(1.0 / 2.2));
|
||||
return pow(max(color, vec3(0.0)), vec3(1.0 / 2.2));
|
||||
case CM_TRANSFER_FUNCTION_GAMMA28:
|
||||
return pow(max(color.rgb, vec3(0.0)), vec3(1.0 / 2.8));
|
||||
return pow(max(color, vec3(0.0)), vec3(1.0 / 2.8));
|
||||
case CM_TRANSFER_FUNCTION_HLG:
|
||||
isLow = lessThanEqual(color.rgb, vec3(HLG_E_CUT));
|
||||
lo = pow(color.rgb / sqrt(3.0), vec3(2.0));
|
||||
hi = (pow(vec3(M_E), (color.rgb - HLG_C) / HLG_A) + HLG_B) / 12.0;
|
||||
return mix(hi, lo, isLow);
|
||||
case CM_TRANSFER_FUNCTION_BT1886:
|
||||
case CM_TRANSFER_FUNCTION_ST240:
|
||||
case CM_TRANSFER_FUNCTION_LOG_100:
|
||||
case CM_TRANSFER_FUNCTION_LOG_316:
|
||||
case CM_TRANSFER_FUNCTION_XVYCC:
|
||||
return tfHLG(color);
|
||||
case CM_TRANSFER_FUNCTION_EXT_SRGB:
|
||||
return tfExtSRGB(color);
|
||||
case CM_TRANSFER_FUNCTION_BT1886:
|
||||
return tfBT1886(color);
|
||||
case CM_TRANSFER_FUNCTION_ST240:
|
||||
return tfST240(color);
|
||||
case CM_TRANSFER_FUNCTION_LOG_100:
|
||||
return mix(1.0 + log(color) / log(10.0) / 2.0, vec3(0.0), lessThanEqual(color, vec3(0.01)));
|
||||
case CM_TRANSFER_FUNCTION_LOG_316:
|
||||
return mix(1.0 + log(color) / log(10.0) / 2.5, vec3(0.0), lessThanEqual(color, vec3(sqrt(10.0) / 1000.0)));
|
||||
case CM_TRANSFER_FUNCTION_XVYCC:
|
||||
return tfXVYCC(color);
|
||||
case CM_TRANSFER_FUNCTION_ST428:
|
||||
|
||||
return pow(max(color, vec3(0.0)) / ST428_SCALE, vec3(1.0 / ST428_POW));
|
||||
case CM_TRANSFER_FUNCTION_SRGB:
|
||||
default:
|
||||
isLow = lessThanEqual(color.rgb, vec3(SRGB_E_CUT));
|
||||
lo = color.rgb * SRGB_LO;
|
||||
hi = pow(color.rgb, vec3(SRGB_INV_POW)) * SRGB_HI - SRGB_HI_ADD;
|
||||
return mix(hi, lo, isLow);
|
||||
return tfSRGB(color);
|
||||
}
|
||||
}
|
||||
|
||||
vec4 fromLinear(vec4 color, int tf) {
|
||||
if (tf == CM_TRANSFER_FUNCTION_EXT_LINEAR)
|
||||
return color;
|
||||
|
||||
|
||||
color.rgb /= max(color.a, 0.001);
|
||||
color.rgb = fromLinearRGB(color.rgb, tf);
|
||||
color.rgb *= color.a;
|
||||
@@ -194,7 +284,7 @@ mat3 primaries2xyz(mat4x2 primaries) {
|
||||
vec3 g = xy2xyz(primaries[1]);
|
||||
vec3 b = xy2xyz(primaries[2]);
|
||||
vec3 w = xy2xyz(primaries[3]);
|
||||
|
||||
|
||||
mat3 invMat = inverse(
|
||||
mat3(
|
||||
r.x, r.y, r.z,
|
||||
@@ -268,7 +358,7 @@ const mat3 ICtCpPQ = mat3(
|
||||
);
|
||||
//const mat3 ICtCpPQInv = inverse(ICtCpPQ);
|
||||
const mat3 ICtCpPQInv = mat3(
|
||||
1.0, 1.0, 1.0,
|
||||
1.0, 1.0, 1.0,
|
||||
0.0086090370379327566, -0.0086090370379327566, 0.560031335710679118,
|
||||
0.11102962500302595656, -0.11102962500302595656, -0.32062717498731885185
|
||||
);
|
||||
@@ -318,19 +408,17 @@ vec4 tonemap(vec4 color, mat3 dstXYZ) {
|
||||
}
|
||||
|
||||
vec4 doColorManagement(vec4 pixColor, int srcTF, int dstTF, mat4x2 dstPrimaries) {
|
||||
pixColor.rgb /= max(pixColor.a, 0.001);
|
||||
pixColor.rgb = toLinearRGB(pixColor.rgb, srcTF);
|
||||
pixColor.rgb /= max(pixColor.a, 0.001);
|
||||
pixColor.rgb = toLinearRGB(pixColor.rgb, srcTF);
|
||||
pixColor.rgb = convertMatrix * pixColor.rgb;
|
||||
pixColor = toNit(pixColor, srcTFRange);
|
||||
pixColor.rgb *= pixColor.a;
|
||||
mat3 dstxyz = primaries2xyz(dstPrimaries);
|
||||
pixColor = tonemap(pixColor, dstxyz);
|
||||
pixColor = fromLinearNit(pixColor, dstTF, dstTFRange);
|
||||
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||
pixColor = saturate(pixColor, dstxyz, sdrSaturation);
|
||||
pixColor.rgb /= pixColor.a;
|
||||
pixColor = toNit(pixColor, srcTFRange);
|
||||
pixColor.rgb *= pixColor.a;
|
||||
mat3 dstxyz = primaries2xyz(dstPrimaries);
|
||||
pixColor = tonemap(pixColor, dstxyz);
|
||||
pixColor = fromLinearNit(pixColor, dstTF, dstTFRange);
|
||||
if (srcTF == CM_TRANSFER_FUNCTION_SRGB && dstTF == CM_TRANSFER_FUNCTION_ST2084_PQ) {
|
||||
pixColor = saturate(pixColor, dstxyz, sdrSaturation);
|
||||
pixColor.rgb *= sdrBrightnessMultiplier;
|
||||
pixColor.rgb *= pixColor.a;
|
||||
}
|
||||
return pixColor;
|
||||
}
|
||||
return pixColor;
|
||||
}
|
||||
|
Reference in New Issue
Block a user