Skip to content

Instantly share code, notes, and snippets.

@damywise
Created November 28, 2023 09:12
Show Gist options
  • Save damywise/e44ebd60acc06a670b29aa39e4bed15a to your computer and use it in GitHub Desktop.
Save damywise/e44ebd60acc06a670b29aa39e4bed15a to your computer and use it in GitHub Desktop.
Dart ITU-R BT.2446 Conversion Method C, From HDR Toys glsl
// ---------------------------------------------------------------------------------------------------------------------------------------
// 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