summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2024-08-19 05:16:26 +0000
committerrodri <rgl@antares-labs.eu>2024-08-19 05:16:26 +0000
commit1ec784ed5ae593f3d382c37c6f34fabe1497a861 (patch)
tree14c25635bb9645ac41ae129858a2e3e9ae911b7b
parent10e8543f5aeabb345fa146c7401ef4ac9eb5df28 (diff)
downloadlibgraphics-1ec784ed5ae593f3d382c37c6f34fabe1497a861.tar.gz
libgraphics-1ec784ed5ae593f3d382c37c6f34fabe1497a861.tar.bz2
libgraphics-1ec784ed5ae593f3d382c37c6f34fabe1497a861.zip
color: add ACES tone mapping functions.
-rw-r--r--color.c71
-rw-r--r--graphics.h2
2 files changed, 73 insertions, 0 deletions
diff --git a/color.c b/color.c
index 13cbef7..fdbd0a0 100644
--- a/color.c
+++ b/color.c
@@ -147,3 +147,74 @@ rgba2xrgb(ulong c)
return (c & 0xFF)<<24|(c>>24 & 0xFF)<<16|
(c>>16 & 0xFF)<<8|(c>>8 & 0xFF);
}
+
+
+/* tone mapping */
+
+/*
+ * simplified ACES filmic tone mapping curve by Krzysztof Narkowicz
+ * https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+ */
+static double
+_aces(double value)
+{
+ double a = 2.51;
+ double b = 0.03;
+ double c = 2.43;
+ double d = 0.59;
+ double e = 0.14;
+ value = (value * (a * value + b)) / (value * (c * value + d) + e);
+ return fclamp(value, 0, 1);
+}
+
+Color
+aces(Color c)
+{
+ c.r = _aces(c.r);
+ c.g = _aces(c.g);
+ c.b = _aces(c.b);
+ return c;
+}
+
+static double
+RRTAndODTFit(double v)
+{
+ double a = v * (v + 0.0245786f) - 0.000090537f;
+ double b = v * (0.983729f * v + 0.4329510f) + 0.238081f;
+ return a / b;
+}
+
+/*
+ * a better ACES curve fit by Stephen Hill (@self_shadow)
+ * https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
+ */
+Color
+aces2(Color c)
+{
+ /* sRGB → XYZ → D65_2_D60 → AP1 → RRT_SAT */
+ Matrix3 ACESInputMat = {
+ 0.59719, 0.35458, 0.04823, 0,
+ 0.07600, 0.90834, 0.01566, 0,
+ 0.02840, 0.13383, 0.83777, 0,
+ 0, 0, 0, 1,
+ };
+ /* ODT_SAT → XYZ → D60_2_D65 → sRGB */
+ Matrix3 ACESOutputMat = {
+ 1.60475, -0.53108, -0.07367, 0,
+ -0.10208, 1.10813, -0.00605, 0,
+ -0.00327, -0.07276, 1.07602, 0,
+ 0, 0, 0, 1,
+ };
+
+ c = xform3(c, ACESInputMat);
+ /* Apply RRT and ODT */
+ c.r = RRTAndODTFit(c.r);
+ c.g = RRTAndODTFit(c.g);
+ c.b = RRTAndODTFit(c.b);
+
+ c = xform3(c, ACESOutputMat);
+ c.r = fclamp(c.r, 0, 1);
+ c.g = fclamp(c.g, 0, 1);
+ c.b = fclamp(c.b, 0, 1);
+ return c;
+}
diff --git a/graphics.h b/graphics.h
index 35d4d0c..42aef67 100644
--- a/graphics.h
+++ b/graphics.h
@@ -418,6 +418,8 @@ Memimage *dupmemimage(Memimage*);
Color srgb2linear(Color);
Color linear2srgb(Color);
ulong rgba2xrgb(ulong);
+Color aces(Color);
+Color aces2(Color);
/* shadeop */
double sign(double);