-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
agx.glsl.js
104 lines (86 loc) · 3.62 KB
/
agx.glsl.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
export default /* glsl */ `
// Missing Deadlines (Benjamin Wrensch): https://iolite-engine.com/blog_posts/minimal_agx_implementation
// Filament: https://github.com/google/filament/blob/main/filament/src/ToneMapper.cpp#L263
// https://github.com/EaryChow/AgX_LUT_Gen/blob/main/AgXBaseRec2020.py
// Three.js: https://github.com/mrdoob/three.js/blob/4993e3af579a27cec950401b523b6e796eab93ec/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js#L79-L89
// Matrices for rec 2020 <> rec 709 color space conversion
// matrix provided in row-major order so it has been transposed
// https://www.itu.int/pub/R-REP-BT.2407-2017
const mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(
1.6605, -0.1246, -0.0182,
-0.5876, 1.1329, -0.1006,
-0.0728, -0.0083, 1.1187
);
const mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(
0.6274, 0.0691, 0.0164,
0.3293, 0.9195, 0.0880,
0.0433, 0.0113, 0.8956
);
// Converted to column major from blender: https://github.com/blender/blender/blob/fc08f7491e7eba994d86b610e5ec757f9c62ac81/release/datafiles/colormanagement/config.ocio#L358
const mat3 AgXInsetMatrix = mat3(
0.856627153315983, 0.137318972929847, 0.11189821299995,
0.0951212405381588, 0.761241990602591, 0.0767994186031903,
0.0482516061458583, 0.101439036467562, 0.811302368396859
);
// Converted to column major and inverted from https://github.com/EaryChow/AgX_LUT_Gen/blob/ab7415eca3cbeb14fd55deb1de6d7b2d699a1bb9/AgXBaseRec2020.py#L25
// https://github.com/google/filament/blob/bac8e58ee7009db4d348875d274daf4dd78a3bd1/filament/src/ToneMapper.cpp#L273-L278
const mat3 AgXOutsetMatrix = mat3(
1.1271005818144368, -0.1413297634984383, -0.14132976349843826,
-0.11060664309660323, 1.157823702216272, -0.11060664309660294,
-0.016493938717834573, -0.016493938717834257, 1.2519364065950405
);
const float AgxMinEv = -12.47393;
const float AgxMaxEv = 4.026069;
// 0: Default, 1: Golden, 2: Punchy
#ifndef AGX_LOOK
#define AGX_LOOK 0
#endif
vec3 agxAscCdl(vec3 color, vec3 slope, vec3 offset, vec3 power, float sat) {
const vec3 lw = vec3(0.2126, 0.7152, 0.0722);
float luma = dot(color, lw);
vec3 c = pow(color * slope + offset, power);
return luma + sat * (c - luma);
}
// Sample usage
vec3 agx(vec3 color) {
color = LINEAR_SRGB_TO_LINEAR_REC2020 * color; // From three.js
// 1. agx()
// Input transform (inset)
color = AgXInsetMatrix * color;
color = max(color, 1e-10); // From Filament: avoid 0 or negative numbers for log2
// Log2 space encoding
color = clamp(log2(color), AgxMinEv, AgxMaxEv);
color = (color - AgxMinEv) / (AgxMaxEv - AgxMinEv);
color = clamp(color, 0.0, 1.0); // From Filament
// Apply sigmoid function approximation
// Mean error^2: 3.6705141e-06
vec3 x2 = color * color;
vec3 x4 = x2 * x2;
color = + 15.5 * x4 * x2
- 40.14 * x4 * color
+ 31.96 * x4
- 6.868 * x2 * color
+ 0.4298 * x2
+ 0.1191 * color
- 0.00232;
// 2. agxLook()
#if AGX_LOOK == 1
// Golden
color = agxAscCdl(color, vec3(1.0, 0.9, 0.5), vec3(0.0), vec3(0.8), 1.3);
#elif AGX_LOOK == 2
// Punchy
color = agxAscCdl(color, vec3(1.0), vec3(0.0), vec3(1.35), 1.4);
#endif
// 3. agxEotf()
// Inverse input transform (outset)
color = AgXOutsetMatrix * color;
// sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display
// NOTE: We're linearizing the output here. Comment/adjust when
// *not* using a sRGB render target
color = pow(max(vec3(0.0), color), vec3(2.2)); // From filament: max()
color = LINEAR_REC2020_TO_LINEAR_SRGB * color; // From three.js
// Gamut mapping. Simple clamp for now.
color = clamp(color, 0.0, 1.0);
return color;
}
`;