Created
November 28, 2023 09:12
-
-
Save damywise/e44ebd60acc06a670b29aa39e4bed15a to your computer and use it in GitHub Desktop.
Dart ITU-R BT.2446 Conversion Method C, From HDR Toys glsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// --------------------------------------------------------------------------------------------------------------------------------------- | |
// ITU-R BT.2446 Conversion Method C | |
// https://www.itu.int/pub/R-REP-BT.2446 | |
//!HOOK OUTPUT | |
//!BIND HOOKED | |
//!DESC tone mapping (bt.2446c) | |
Vector3 RGB_to_XYZ(Vector3 RGB) { | |
Matrix3 M = Matrix3( | |
0.6369580483012914, | |
0.14461690358620832, | |
0.1688809751641721, | |
0.2627002120112671, | |
0.6779980715188708, | |
0.05930171646986196, | |
0.000000000000000, | |
0.028072693049087428, | |
1.060985057710791); | |
return RGB..applyMatrix3(M); | |
} | |
Vector3 XYZ_to_RGB(Vector3 XYZ) { | |
Matrix3 M = Matrix3( | |
1.716651187971268, | |
-0.355670783776392, | |
-0.253366281373660, | |
-0.666684351832489, | |
1.616481236634939, | |
0.0157685458139111, | |
0.017639857445311, | |
-0.042770613257809, | |
0.942103121235474); | |
return XYZ..applyMatrix3(M); | |
} | |
Vector3 XYZ_to_xyY(Vector3 XYZ) { | |
double X = XYZ.x; | |
double Y = XYZ.y; | |
double Z = XYZ.z; | |
double divisor = X + Y + Z; | |
if (divisor == 0.0) divisor = 1e-6; | |
double x = X / divisor; | |
double y = Y / divisor; | |
return Vector3(x, y, Y); | |
} | |
Vector3 xyY_to_XYZ(Vector3 xyY) { | |
double x = xyY.x; | |
double y = xyY.y; | |
double Y = xyY.z; | |
double multiplo = Y / max(y, 1e-6); | |
double z = 1.0 - x - y; | |
double X = x * multiplo; | |
double Z = z * multiplo; | |
return Vector3(X, Y, Z); | |
} | |
const double ip = 0.58535; // linear length | |
const double k1 = 0.83802; // linear strength | |
const double k3 = 0.74204; // shoulder strength | |
double f2(double Y, double k1, double k3, double ip) { | |
ip /= k1; | |
double k2 = (k1 * ip) * (1.0 - k3); | |
double k4 = (k1 * ip) - (k2 * log(1.0 - k3)); | |
return Y < ip ? Y * k1 : log((Y / ip) - k3) * k2 + k4; | |
} | |
double curve2(double x) { | |
const double over_white = 1019.0 / 940.0; // 109% range (super-whites) | |
return f2(x, k1, k3, ip) / over_white; | |
} | |
Vector4 hook3(double r, double g, double b) { | |
Vector4 color = Vector4(r, g, b, 1.0); | |
color.rgb = RGB_to_XYZ(color.rgb); | |
color.rgb = XYZ_to_xyY(color.rgb); | |
// color.z = curve2(color.z); | |
color.rgb = xyY_to_XYZ(color.rgb); | |
color.rgb = XYZ_to_RGB(color.rgb); | |
return color; | |
} | |
void applyToneMapping2446c(Float32List hdrImage) { | |
for (int i = 0; i < hdrImage.length; i += 3) { | |
final color = hook3(hdrImage[i], hdrImage[i + 1], hdrImage[i + 2]); | |
hdrImage[i] = color.x; | |
hdrImage[i + 1] = color.y; | |
hdrImage[i + 2] = color.z; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment