\nReferences\nSimple estimation methods for the Helmholtz—Kohlrausch effect\nYoshinobu Nayatani\nhttps://doi.org/10.1002/(SICI)1520-6378(199712)22:6<385::AID-COL6>3.0.CO;2-R\n\nClarification of differences between variable achromatic color and variable chromatic color methods in the Helmholtz–Kohlrausch effect\nYoshinobu Nayatani, Hideki Sakai\nhttps://doi.org/10.1002/col.20194\n\nPrediction of the Helmholtz-Kohlrausch effect using the CIELUV formula\nYoshinobu Nayatani, Motohiro Nakajima\nhttps://doi.org/10.1002/(SICI)1520-6378(199608)21:4<252::AID-COL1>3.0.CO;2-P"
17 | note_font_size 14
18 | note_font_color 0xa8a8a8ff
19 | xpos 115
20 | ypos -119
21 | }
22 | Input {
23 | inputs 0
24 | name Input
25 | xpos -40
26 | ypos -154
27 | }
28 | Dot {
29 | name Dot1
30 | xpos -6
31 | ypos -78
32 | }
33 | set N9a8c2b00 [stack 0]
34 | Group {
35 | name InGamut_to_XYZ
36 | tile_color 0x429940ff
37 | xpos -150
38 | ypos -82
39 | addUserKnob {20 InputGamut_to_XYZ_tab l InputGamut_to_XYZ}
40 | addUserKnob {4 gamut l "input gamut" M {ACES ACEScg P3D65 Rec.2020 Rec.709 "Alexa WideGamut" "Red WideGamutRGB" "Sony SGamut3" "Filmlight E-Gamut" "DaVinci Wide Gamut" "" ""}}
41 | gamut ACEScg
42 | addUserKnob {41 matrix T ColorMatrix.matrix}
43 | addUserKnob {41 invert -STARTLINE T ColorMatrix.invert}
44 | }
45 | Input {
46 | inputs 0
47 | name Input
48 | xpos 290
49 | ypos -610
50 | }
51 | Dot {
52 | name Dot1
53 | xpos 324
54 | ypos -546
55 | }
56 | set N9a8c1600 [stack 0]
57 | ColorMatrix {
58 | matrix {
59 | {{"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"}}
60 | {{"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"}}
61 | {{"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"} {"SwitchGamut.input\[value SwitchGamut.which].matrix"}}
62 | }
63 | name ColorMatrix
64 | xpos 290
65 | ypos -370
66 | }
67 | Output {
68 | name Output
69 | xpos 290
70 | ypos -250
71 | }
72 | push $N9a8c1600
73 | Dot {
74 | name Dot391
75 | label " *RGB to XYZ D65 CAT: XYZ Scaling"
76 | xpos 434
77 | ypos -546
78 | }
79 | set N9a8c0100 [stack 0]
80 | ColorMatrix {
81 | matrix {
82 | {0.7006223202 0.1487748027 0.101058729}
83 | {0.2741184831 0.8736317754 -0.1477504224}
84 | {-0.09896290302 -0.1378953159 1.325916052}
85 | }
86 | name ColorMatrix30
87 | label "DaVinci WG to XYZ D65"
88 | xpos 1390
89 | ypos -466
90 | }
91 | push $N9a8c0100
92 | ColorMatrix {
93 | matrix {
94 | {0.705396831 0.1640413404 0.08101775497}
95 | {0.2801307142 0.8202067018 -0.1003373787}
96 | {-0.1037815139 -0.07290726155 1.265746593}
97 | }
98 | name ColorMatrix29
99 | label "Filmlight E-Gamut to XYZ D65"
100 | xpos 1280
101 | ypos -466
102 | }
103 | push $N9a8c0100
104 | ColorMatrix {
105 | matrix {
106 | {0.5990839005 0.2489254922 0.1024464965}
107 | {0.2150758207 0.8850684166 -0.1001443192}
108 | {-0.03206584975 -0.02765838802 1.148782015}
109 | }
110 | name ColorMatrix31
111 | label "SonySGamut3 to XYZ D65"
112 | xpos 1170
113 | ypos -465
114 | }
115 | push $N9a8c0100
116 | ColorMatrix {
117 | matrix {
118 | {0.735275209 0.06860940903 0.1465712786}
119 | {0.2866940796 0.8429790735 -0.1296732426}
120 | {-0.07968084514 -0.3473432064 1.516081929}
121 | }
122 | name ColorMatrix22
123 | label "REDWideGamutRGB to XYZ D65"
124 | xpos 1060
125 | ypos -466
126 | }
127 | push $N9a8c0100
128 | ColorMatrix {
129 | matrix {
130 | {0.6380076408 0.2147038132 0.09774445742}
131 | {0.2919537723 0.8238408566 -0.1157948226}
132 | {0.002798279049 -0.06703422219 1.153293848}
133 | }
134 | name ColorMatrix21
135 | label "Arri AlexaWideGamut to XYZ D65"
136 | xpos 950
137 | ypos -466
138 | }
139 | push $N9a8c0100
140 | ColorMatrix {
141 | matrix {
142 | {0.4123909175 0.3575843573 0.1804807931}
143 | {0.2126390785 0.7151687145 0.07219231129}
144 | {0.01933082566 0.1191947833 0.9505321383}
145 | }
146 | name ColorMatrix18
147 | label "Rec709 to XYZ D65"
148 | xpos 840
149 | ypos -466
150 | }
151 | push $N9a8c0100
152 | ColorMatrix {
153 | matrix {
154 | {0.6369581223 0.1446169168 0.1688809693}
155 | {0.2627002299 0.6779981256 0.05930171534}
156 | {4.99410725e-17 0.02807269618 1.060985088}
157 | }
158 | name ColorMatrix17
159 | label "Rec2020 to XYZ D65"
160 | xpos 730
161 | ypos -466
162 | }
163 | push $N9a8c0100
164 | ColorMatrix {
165 | matrix {
166 | {0.4865711331 0.2656677067 0.1982173175}
167 | {0.2289746404 0.6917386055 0.07928691804}
168 | {-3.972076965e-17 0.04511338845 1.043944478}
169 | }
170 | name ColorMatrix16
171 | label "P3D65 to XYZ D65"
172 | xpos 620
173 | ypos -466
174 | }
175 | push $N9a8c0100
176 | ColorMatrix {
177 | matrix {
178 | {0.6609312296 0.1336961389 0.1558285803}
179 | {0.2722287476 0.6740817428 0.05368950963}
180 | {-0.006018006243 0.004383686464 1.090692043}
181 | }
182 | name ColorMatrix1
183 | label "ACEScg to XYZ D65"
184 | xpos 510
185 | ypos -466
186 | }
187 | push $N9a8c0100
188 | ColorMatrix {
189 | matrix {
190 | {0.9503623843 0 9.346324805e-05}
191 | {0.3439664543 0.728166163 -0.07213254273}
192 | {0 0 1.089057803}
193 | }
194 | name ColorMatrix2
195 | label "ACES to XYZ D65"
196 | xpos 400
197 | ypos -466
198 | }
199 | Switch {
200 | inputs 10
201 | which {{gamut}}
202 | name SwitchGamut
203 | xpos 400
204 | ypos -370
205 | }
206 | end_group
207 | Expression {
208 | temp_name0 f
209 | temp_expr0 0
210 | expr0 max(0,r+f)
211 | expr1 max(0,g+f)
212 | expr2 max(0,b+f)
213 | name Clamp
214 | xpos -150
215 | ypos -57
216 | }
217 | Expression {
218 | temp_name0 d
219 | temp_expr0 (r+15*g+3*b)
220 | temp_name1 L
221 | temp_expr1 g>_e?116*pow(g,1/3)-16:g*_k
222 | expr0 L/(n?100:1)
223 | expr1 d==0?0:4*r/d
224 | expr2 d==0?0:9*g/d
225 | name XYZ_to_Luv
226 | label "XYZ to L*u'v'"
227 | xpos -150
228 | ypos -15
229 | addUserKnob {20 Params}
230 | addUserKnob {7 _e}
231 | _e {{216/24389}}
232 | addUserKnob {7 _k}
233 | _k {{24389/27}}
234 | addUserKnob {6 n l normalize +STARTLINE}
235 | n true
236 | }
237 | Expression {
238 | temp_name0 h
239 | temp_expr0 atan2(b-w_uv.1,g-w_uv.0)
240 | temp_name1 th
241 | temp_expr1 h<0?h+radians(360):h
242 | temp_name2 q
243 | temp_expr2 -0.01585-0.03017*cos(th)-0.04556*cos(2*th)-0.02667*cos(3*th)-0.00295*cos(4*th)+0.14592*sin(th)+0.05084*sin(2*th)-0.01900*sin(3*th)-0.00764*sin(4*th)
244 | temp_name3 S_uv
245 | temp_expr3 13*hypot(g-w_uv.0,b-w_uv.1)
246 | channel0 {rgba.red rgba.green rgba.blue none}
247 | expr0 1/(1+(m*q+0.0872*K_Br)*S_uv)
248 | name Nayatani1997_
249 | label "object colors"
250 | xpos -150
251 | ypos 33
252 | addUserKnob {20 Params_tab l Params}
253 | addUserKnob {4 illum M {D50 D55 D60 D65}}
254 | illum D65
255 | addUserKnob {78 w_xy n 2}
256 | w_xy {{curve(illum) 0.3457 0.33243 0.321626 0.3127} {curve(illum) 0.3585 0.34744 0.337737 0.329}}
257 | addUserKnob {78 w_uv n 2}
258 | w_uv {{4*w_xy.0/(-2*w_xy.0+12*w_xy.1+3)} {9*w_xy.1/(-2*w_xy.0+12*w_xy.1+3)}}
259 | addUserKnob {7 La t "adapting luminance" R 0 200}
260 | La 63.61
261 | addUserKnob {4 meth l method M {VAC VCC}}
262 | meth VCC
263 | addUserKnob {7 m R -4 4}
264 | m {{meth?-0.134:-0.866}}
265 | addUserKnob {7 K_Br R 0 10}
266 | K_Br {{0.2717*(6.469+6.362*pow(La,0.4495))/(6.469+pow(La,0.4495))}}
267 | }
268 | push $N9a8c2b00
269 | MergeExpression {
270 | inputs 2
271 | expr0 invert?Br/Ar:Ar*Br
272 | expr1 invert?Bg/Ag:Ag*Bg
273 | expr2 invert?Bb/Ab:Ab*Bb
274 | name MergeExpression1
275 | xpos -40
276 | ypos 39
277 | }
278 | Output {
279 | name Output
280 | xpos -40
281 | ypos 110
282 | }
283 | end_group
284 |
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/Purity.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name Purity
5 | tile_color 0x536177ff
6 | addUserKnob {20 Params_tab l Params}
7 | addUserKnob {26 about_label l " " T "\n\nPurity created by Jed Smith\n
v0.0.1 | documentation
"}
8 | addUserKnob {41 purity T PivotedPowerCubic.purity}
9 | addUserKnob {41 p l strength T PivotedPowerCubic.p}
10 | addUserKnob {26 ""}
11 | addUserKnob {41 rw l "red weight" T Weights.rw}
12 | addUserKnob {41 bw l "blue weight" T Weights.bw}
13 | }
14 | Input {
15 | inputs 0
16 | name Input
17 | xpos 840
18 | ypos 518
19 | }
20 | Dot {
21 | name Dot3
22 | xpos 874
23 | ypos 570
24 | }
25 | set N905fd3b0 [stack 0]
26 | Expression {
27 | channel0 rgba
28 | expr0 max(r,g,b)
29 | name MaxRGB
30 | xpos 950
31 | ypos 566
32 | }
33 | set N8a410980 [stack 0]
34 | Dot {
35 | name Dot4
36 | xpos 984
37 | ypos 738
38 | }
39 | push $N8a410980
40 | push $N905fd3b0
41 | MergeExpression {
42 | inputs 2
43 | expr0 Ar==0?0:max(-2,Br/Ar)
44 | expr1 Ag==0?0:max(-2,Bg/Ag)
45 | expr2 Ab==0?0:max(-2,Bb/Ab)
46 | name MergeDivideReverse
47 | xpos 840
48 | ypos 590
49 | }
50 | set N49773530 [stack 0]
51 | Expression {
52 | expr0 1-r
53 | expr1 1-g
54 | expr2 1-b
55 | expr3 1-a
56 | name invert
57 | xpos 730
58 | ypos 590
59 | }
60 | Expression {
61 | temp_name2 L
62 | temp_expr2 (r*rw+g*gw+b*bw)
63 | temp_name3 c
64 | temp_expr3 max(r,g,b)
65 | channel0 {rgba.red -rgba.green -rgba.blue none}
66 | expr0 c==0?L:L/c
67 | expr1 max(0,1-L)
68 | expr3 c
69 | name Weights
70 | label "\n"
71 | xpos 730
72 | ypos 614
73 | addUserKnob {20 Params}
74 | addUserKnob {7 rw R 0.05 0.6}
75 | rw 0.25
76 | addUserKnob {7 gw}
77 | gw {{1-(rw+bw)}}
78 | addUserKnob {7 bw R 0.05 0.6}
79 | bw 0.1
80 | }
81 | Expression {
82 | temp_name0 c
83 | temp_expr0 a
84 | temp_name1 cc
85 | temp_expr1 1-c
86 | temp_name2 f0
87 | temp_expr2 c**p*(a0*c+b0)+m
88 | temp_name3 f1
89 | temp_expr3 c<=0?1:(1-cc*(cc**p*(a0*cc+b0)+m))/c
90 | channel0 rgb
91 | expr3 max(0,purity>0?(r*f1+(1-r)):((1-r)*f0+r))
92 | name PivotedPowerCubic
93 | label https://www.desmos.com/calculator/bdbstdsvvv
94 | xpos 730
95 | ypos 656
96 | addUserKnob {20 Params}
97 | addUserKnob {7 purity R -1 1}
98 | addUserKnob {7 p l power R 0 4}
99 | p 2
100 | addUserKnob {7 m}
101 | m {{1-fabs(purity)}}
102 | addUserKnob {26 ""}
103 | addUserKnob {7 a0 R -10 10}
104 | a0 {{p*(m-1)}}
105 | addUserKnob {7 b0 R -10 10}
106 | b0 {{(1-m)*(p+1)}}
107 | }
108 | push $N49773530
109 | MergeExpression {
110 | inputs 2
111 | temp_name0 f
112 | temp_expr0 Aa
113 | temp_name1 L
114 | temp_expr1 Ag
115 | expr0 L*(1-f)+r*f
116 | expr1 L*(1-f)+g*f
117 | expr2 L*(1-f)+b*f
118 | name ChromaLerp
119 | xpos 840
120 | ypos 686
121 | }
122 | Merge2 {
123 | inputs 2
124 | operation multiply
125 | bbox B
126 | output rgb
127 | name MergeMultiply
128 | xpos 840
129 | ypos 734
130 | }
131 | Output {
132 | name Output
133 | xpos 840
134 | ypos 782
135 | }
136 | end_group
137 |
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/Saturation.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name Saturation
5 | tile_color 0x536177ff
6 | addUserKnob {20 Saturation_tab l Saturation}
7 | addUserKnob {26 global_label l " " T global}
8 | addUserKnob {41 sag l sat T Saturation.sag}
9 | addUserKnob {26 huesat_label l " " T hue}
10 | addUserKnob {41 sah l sat T Saturation.sah}
11 | addUserKnob {32 sr l "R" T "knobs this \{ho 2\}" +STARTLINE}
12 | addUserKnob {32 sg l "G" -STARTLINE T "knobs this \{ho 6\}"}
13 | addUserKnob {32 sb l "B" -STARTLINE T "knobs this \{ho 4\}"}
14 | addUserKnob {32 sc l "C" -STARTLINE T "knobs this \{ho 5\}"}
15 | addUserKnob {32 sm l "M" -STARTLINE T "knobs this \{ho 3\}"}
16 | addUserKnob {32 sy l "Y" -STARTLINE T "knobs this \{ho 1\}"}
17 | addUserKnob {41 ho l hue T HueAngle.ho}
18 | addUserKnob {41 w l width T HueAngle.w}
19 | addUserKnob {26 luminance_weights_label l " " T "luminance weights"}
20 | addUserKnob {35 lw_presets l " " t "select luminance weight preset" -STARTLINE M {preset/ACEScg "knobs this \{wr 0.26806405 wb 0.05947147\}" preset/Rec.2020 "knobs this \{wr 0.26270026 wb 0.05930173\}" preset/P3D65 "knobs this \{wr 0.22897467 wb 0.07928693\}" preset/Rec.709 "knobs this \{wr 0.21263911 wb 0.07219233\}"}}
21 | addUserKnob {41 wr T Saturation.wr}
22 | addUserKnob {41 wb T Saturation.wb}
23 | addUserKnob {6 lg l "in log" t "applies saturation in -7 +7 stop lg2 " +STARTLINE}
24 | addUserKnob {41 invert t "invert the saturation adjustment. Warning: not supported with zone limiting, nor with log" T Saturation.invert}
25 | addUserKnob {26 ""}
26 | addUserKnob {26 zonelimit_label l " " T "zone limiting"}
27 | addUserKnob {6 ze l zoned t "enable zone limiting." +STARTLINE}
28 | addUserKnob {83 zr l "" -STARTLINE M {low high}}
29 | addUserKnob {7 zp l "zone range" t "set range affected: higher values affect a larger range" R -4 4}
30 | addUserKnob {26 ""}
31 | addUserKnob {41 maskChannelMask l mask -STARTLINE T NodeWrapper1.maskChannelMask}
32 | addUserKnob {41 invert_mask l invert -STARTLINE T NodeWrapper1.invert_mask}
33 | addUserKnob {41 mix T NodeWrapper1.mix}
34 | }
35 | Input {
36 | inputs 0
37 | name Inputmask
38 | xpos 290
39 | ypos -514
40 | number 1
41 | }
42 | Input {
43 | inputs 0
44 | name Input
45 | xpos 180
46 | ypos -730
47 | }
48 | Dot {
49 | name Dot7
50 | xpos 214
51 | ypos -702
52 | }
53 | set N2adc9910 [stack 0]
54 | Expression {
55 | temp_name0 n
56 | temp_expr0 max(1e-12,max(r,g,b))
57 | temp_name1 to
58 | temp_expr1 (n*n/(n+fl))
59 | temp_name2 flow
60 | temp_expr2 pow((to/(to+1))/n,p)
61 | temp_name3 fhi
62 | temp_expr3 1-pow((n/(n+1))/n,p)
63 | channel0 {rgba.red -rgba.green -rgba.blue none}
64 | expr0 r
65 | expr1 g
66 | expr2 b
67 | expr3 zr?fhi:flow
68 | name Extract
69 | xpos 70
70 | ypos -634
71 | addUserKnob {20 Params}
72 | addUserKnob {7 fl R 0 0.02}
73 | fl 0.01
74 | addUserKnob {7 p R 0 64}
75 | p {{pow(2,-zp)}}
76 | }
77 | push $N2adc9910
78 | Expression {
79 | temp_name0 M
80 | temp_expr0 max(r,g,b)
81 | temp_name1 C
82 | temp_expr1 M-min(r,g,b)
83 | temp_name2 H
84 | temp_expr2 (C==0?0:r==M?((g-b)/C+6)%6:g==M?(b-r)/C+2:b==M?(r-g)/C+4:0)
85 | temp_name3 h
86 | temp_expr3 (H+ho)%6
87 | channel0 rgba
88 | expr0 hsp?(log(dr/0.18)/log(2)-mn)/(mx-mn):(dr-sp)/ls+lo
115 | expr1 dg>sp?(log(dg/0.18)/log(2)-mn)/(mx-mn):(dg-sp)/ls+lo
116 | expr2 db>sp?(log(db/0.18)/log(2)-mn)/(mx-mn):(db-sp)/ls+lo
117 | name lin_to_log_lx
118 | xpos 180
119 | ypos -658
120 | disable {{!lg}}
121 | addUserKnob {20 Params}
122 | addUserKnob {7 mn R -12 0}
123 | mn -7
124 | addUserKnob {7 mx R 0 12}
125 | mx 7
126 | addUserKnob {7 sp t "splice point"}
127 | sp {{2**-7}}
128 | addUserKnob {7 lo t "linear offset"}
129 | lo {{(log(sp/0.18)/log(2)-mn)/(mx-mn)}}
130 | addUserKnob {7 ls t "linear slope"}
131 | ls {{sp*(mx-mn)*log(2)}}
132 | }
133 | MergeExpression {
134 | inputs 2
135 | temp_name0 L
136 | temp_expr0 wr*r+wg*g+wb*b
137 | temp_name1 f
138 | temp_expr1 (1-Ar+sah*Ar)*sag
139 | expr0 invert?(L*(f-1)+r)/f:L*(1-f)+r*f
140 | expr1 invert?(L*(f-1)+g)/f:L*(1-f)+g*f
141 | expr2 invert?(L*(f-1)+b)/f:L*(1-f)+b*f
142 | expr3 f
143 | name Saturation
144 | selected true
145 | xpos 180
146 | ypos -634
147 | addUserKnob {20 Params}
148 | addUserKnob {7 sag l saturation R 0 2}
149 | sag 1
150 | addUserKnob {7 sah l saturation R 0 2}
151 | sah 1
152 | addUserKnob {7 wr}
153 | wr 0.23
154 | addUserKnob {7 wg}
155 | wg {{1-(wr+wb)}}
156 | addUserKnob {7 wb}
157 | wb 0.08
158 | addUserKnob {6 invert +STARTLINE}
159 | }
160 | Expression {
161 | temp_name0 dr
162 | temp_expr0 r>lo?0.18*pow(2,(r*(mx-mn)+mn)):ls*(r-lo)+sp
163 | temp_name1 dg
164 | temp_expr1 g>lo?0.18*pow(2,(g*(mx-mn)+mn)):ls*(g-lo)+sp
165 | temp_name2 db
166 | temp_expr2 b>lo?0.18*pow(2,(b*(mx-mn)+mn)):ls*(b-lo)+sp
167 | temp_name3 n
168 | temp_expr3 max(dr,dg,db)
169 | expr0 dr*1.25-n/4
170 | expr1 dg*1.25-n/4
171 | expr2 db*1.25-n/4
172 | name log_to_lin_lx
173 | xpos 180
174 | ypos -610
175 | disable {{!lg}}
176 | addUserKnob {20 Params}
177 | addUserKnob {7 mn R -12 0}
178 | mn -7
179 | addUserKnob {7 mx R 0 12}
180 | mx 7
181 | addUserKnob {7 sp t "splice point"}
182 | sp {{2**-7}}
183 | addUserKnob {7 lo t "linear offset"}
184 | lo {{(log(sp/0.18)/log(2)-mn)/(mx-mn)}}
185 | addUserKnob {7 ls t "linear slope"}
186 | ls {{sp*(mx-mn)*log(2)}}
187 | }
188 | MergeExpression {
189 | inputs 2
190 | temp_name0 f
191 | temp_expr0 ze?Aa:1
192 | expr0 Ar*(1-f)+Br*f
193 | expr1 Ag*(1-f)+Bg*f
194 | expr2 Ab*(1-f)+Bb*f
195 | name Mix1
196 | xpos 180
197 | ypos -561
198 | }
199 | push $N2adc9910
200 | NodeWrapper {
201 | inputs 2+1
202 | channels rgb
203 | name NodeWrapper1
204 | xpos 180
205 | ypos -514
206 | }
207 | Output {
208 | name Output
209 | xpos 180
210 | ypos -466
211 | }
212 | end_group
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/ShadowContrast.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name ShadowContrast
5 | addUserKnob {20 ShadowContrast_tab l ShadowContrast}
6 | addUserKnob {41 ex l exposure T expr_ShadowContrast.ex}
7 | addUserKnob {41 str l strength T expr_ShadowContrast.str}
8 | addUserKnob {41 invert T expr_ShadowContrast.invert}
9 | addUserKnob {26 ""}
10 | addUserKnob {41 maskChannelMask l mask -STARTLINE T expr_ShadowContrast.maskChannelMask}
11 | addUserKnob {41 invert_mask l invert -STARTLINE T expr_ShadowContrast.invert_mask}
12 | addUserKnob {41 mix T expr_ShadowContrast.mix}
13 | }
14 | Input {
15 | inputs 0
16 | name Inputmask
17 | xpos -1140
18 | ypos -106
19 | number 1
20 | }
21 | Input {
22 | inputs 0
23 | name Input
24 | xpos -1250
25 | ypos -154
26 | }
27 | Expression {
28 | inputs 1+1
29 | temp_name0 p0
30 | temp_expr0 max(r,g,b)**2-3*_m*w
31 | temp_name1 p1
32 | temp_expr1 2*max(r,g,b)**2+27*w-9*_m*w
33 | temp_name2 p2
34 | temp_expr2 pow(sqrt(max(r,g,b)**2*p1*p1-4*p0*p0*p0)/2+max(r,g,b)*p1/2,1/3)
35 | temp_name3 s
36 | temp_expr3 invert?((max(r,g,b)**2-3*_m*w)/(3*p2)+p2/3+max(r,g,b)/3)/max(r,g,b):(max(r,g,b)**2+_m*w)/(max(r,g,b)**2+w)
37 | expr0 r*s
38 | expr1 g*s
39 | expr2 b*s
40 | name expr_ShadowContrast
41 | label "https://www.desmos.com/calculator/ubgteikoke\nhttps://colab.research.google.com/drive/1JT_-S96RZyfHPkZ620QUPIRfxmS_rKlx"
42 | xpos -1250
43 | ypos -118
44 | addUserKnob {20 Params}
45 | addUserKnob {7 ex l exposure R -6 0}
46 | addUserKnob {7 str l strength}
47 | str 0.5
48 | addUserKnob {7 _m R 0 4}
49 | _m {{2**ex}}
50 | addUserKnob {7 w}
51 | w {{str**3}}
52 | addUserKnob {6 invert +STARTLINE}
53 | }
54 | Output {
55 | name Output
56 | xpos -1250
57 | ypos -58
58 | }
59 | end_group
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/XLog.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Expression {
4 | expr0 invert?rxlog
\nClassic Cineon style log space for grading, similar to Filmlight's T-Log.\nxloghalf
\nCineon style log space with less dynamic range up to 16. suitable for log grading in half float maybe?\nxlogc
\nCamera encoding style log curve with an extended linear section in in the shadows.\n\n" M {presets/xlog "knobs this \{w0 128 w1 1 o 7.5 k 0.06 x0 0 y0 0.075\}" presets/xloghalf "knobs this \{w0 16 w1 1 o 6.7 k 0.05 x0 0 y0 0.092\}" presets/xlogc "knobs this \{w0 64 w1 1 o 7 k 0.18 x0 0.01 y0 0.15\}" ""}}
11 | addUserKnob {7 w0 t "w0 defines the x intersection point at y=w1" R 10 256}
12 | w0 16
13 | addUserKnob {7 w1 R 0 2}
14 | w1 1
15 | addUserKnob {7 o R 0 12}
16 | o 6.7
17 | addUserKnob {7 k t "k = slope on log function at linear extension point (x1, y1)" R 0 0.2}
18 | k 0.05
19 | addUserKnob {7 x0 t "intersection constraint for lower x coordinate" R 0 0.5}
20 | addUserKnob {7 y0 t "intersection constraint for lower y coordinate" R 0 0.5}
21 | y0 0.092
22 | addUserKnob {7 o0 t "x offset: the y asymptote of the log curve" R -0.1 0}
23 | o0 {{-(2**-o)}}
24 | addUserKnob {7 s0 t "s0 = scale factor to satisfy intersection constraint at (x0, y0)" R 0 4}
25 | s0 {{(w1-y0)/log((w0-o0)/(x0-o0))}}
26 | addUserKnob {7 o1 t "y offset to satisfy intersection constraint at (w0, w1)" R -1 1}
27 | o1 {{w1-s0*log(w0-o0)}}
28 | addUserKnob {7 x1 t "x1 is x coordinate of linear extension intercept (controlled by user-specified slope k)" R -1 1}
29 | x1 {{s0*log(k*s0*exp(o1/s0))}}
30 | addUserKnob {7 y1 t "y1 is y coordinate of linear extension intercept" R -1 1}
31 | y1 {{exp((x1-o1)/s0)+o0}}
32 | addUserKnob {7 y2 t "y (x=0) intercept of linear equation" R -1 1}
33 | y2 {{y1-k*x1}}
34 | addUserKnob {6 invert +STARTLINE}
35 | }
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/ZoneGrade.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name ZoneGrade
5 | addUserKnob {20 ZoneGrade_tab l ZoneGrade}
6 | addUserKnob {26 global_label l " @b;global" T " \n"}
7 | addUserKnob {7 ge l exposure R -4 4}
8 | addUserKnob {7 go l offset R -0.02 0.02}
9 | addUserKnob {7 gc l contrast R 0.1 2}
10 | gc 1
11 | addUserKnob {7 gcp l pivot R -4 4}
12 | addUserKnob {26 zones_label l "@b;zones" T "\n"}
13 | addUserKnob {20 zones_grp l "" +STARTLINE n -2}
14 | addUserKnob {20 z1_grp l "high / low"}
15 | addUserKnob {26 zone_high_label l " " T high}
16 | addUserKnob {7 he l exposure R -4 4}
17 | addUserKnob {7 hp l pivot R -4 4}
18 | hp -1
19 | addUserKnob {7 hf l falloff}
20 | hf 0.6
21 | addUserKnob {26 zone_low_label l " " T low}
22 | addUserKnob {7 le l exposure R -4 4}
23 | addUserKnob {6 lo_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
24 | addUserKnob {7 lp l pivot R -4 4}
25 | lp 1
26 | addUserKnob {7 lf l falloff}
27 | lf 0.6
28 | addUserKnob {20 z2_grp l "higher / lower"}
29 | addUserKnob {26 zone_higher_label l " " T higher}
30 | addUserKnob {7 he2 l exposure R -4 4}
31 | addUserKnob {7 hp2 l pivot R -4 4}
32 | hp2 1
33 | addUserKnob {7 hf2 l falloff}
34 | hf2 0.6
35 | addUserKnob {26 zone_lower_label l " " T lower}
36 | addUserKnob {7 le2 l exposure R -4 4}
37 | addUserKnob {6 lo2_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
38 | addUserKnob {7 lp2 l pivot R -4 4}
39 | lp2 -1
40 | addUserKnob {7 lf2 l falloff}
41 | lf2 0.6
42 | addUserKnob {20 endGroup n -3}
43 | addUserKnob {26 ""}
44 | addUserKnob {41 maskChannelMask l mask T NodeWrapper.maskChannelMask}
45 | addUserKnob {41 invert_mask l invert -STARTLINE T NodeWrapper.invert_mask}
46 | addUserKnob {41 mix T NodeWrapper.mix}
47 | }
48 | Input {
49 | inputs 0
50 | name Inputmask
51 | xpos -40
52 | ypos 62
53 | number 1
54 | }
55 | Input {
56 | inputs 0
57 | name Input
58 | xpos -260
59 | ypos -130
60 | }
61 | set Nd7e1600 [stack 0]
62 | Expression {
63 | temp_name0 n
64 | temp_expr0 max(r,g,b)/p
65 | temp_name1 s
66 | temp_expr1 co==1?_m:n>0?pow(n,co-1)*_m:1
67 | expr0 (r+o)*s
68 | expr1 (g+o)*s
69 | expr2 (b+o)*s
70 | name expr_global
71 | xpos -260
72 | ypos -82
73 | addUserKnob {20 Params}
74 | addUserKnob {7 off l offset R -0.1 0.1}
75 | off {{go}}
76 | addUserKnob {7 ex l exposure R -4 4}
77 | ex {{ge}}
78 | addUserKnob {7 co l contrast R 0.1 2}
79 | co {{gc}}
80 | addUserKnob {7 pv l pivot R -4 4}
81 | pv {{gcp}}
82 | addUserKnob {7 _m R 0 10}
83 | _m {{pow(2,ex)}}
84 | addUserKnob {7 p R 0 4}
85 | p {{0.18*pow(2,pv)}}
86 | addUserKnob {7 o R -0.1 0.1}
87 | o {{this.off}}
88 | }
89 | Expression {
90 | temp_name0 n
91 | temp_expr0 max(r,g,b)
92 | temp_name1 s
93 | temp_expr1 nx1?(_m*(n-x1)+y1)/n:(_a*pow(n,p)+_b)/n
94 | expr0 r*s
95 | expr1 g*s
96 | expr2 b*s
97 | name exp_high
98 | xpos -260
99 | ypos -34
100 | addUserKnob {20 Params}
101 | addUserKnob {7 ex l exposure R -4 4}
102 | ex {{he}}
103 | addUserKnob {7 pv l pivot R -4 4}
104 | pv {{hp}}
105 | addUserKnob {7 fa l falloff}
106 | fa {{hf}}
107 | addUserKnob {7 f R 0 4}
108 | f {{5*pow(fa,1.6)+1}}
109 | addUserKnob {7 p R 0 10}
110 | p {{fabs(ex+f)<1e-8?1e-8:(ex+f)/f}}
111 | addUserKnob {7 _m R 0 10}
112 | _m {{pow(2,ex)}}
113 | addUserKnob {7 t0}
114 | t0 {{0.18*pow(2,pv)}}
115 | addUserKnob {7 _a R -10 10}
116 | _a {{pow(t0,1-p)/p}}
117 | addUserKnob {7 _b R -10 10}
118 | _b {{t0*(1-1/p)}}
119 | addUserKnob {7 x1 R -10 10}
120 | x1 {{t0*pow(2,f)}}
121 | addUserKnob {7 y1 R -10 10}
122 | y1 {{_a*pow(x1,p)+_b}}
123 | }
124 | Expression {
125 | temp_name0 n
126 | temp_expr0 max(r,g,b)
127 | temp_name1 s
128 | temp_expr1 nx1?(_m*(n-x1)+y1)/n:(_a*pow(n,p)+_b)/n
129 | expr0 r*s
130 | expr1 g*s
131 | expr2 b*s
132 | name exp_higher
133 | xpos -260
134 | ypos -10
135 | addUserKnob {20 Params}
136 | addUserKnob {7 ex l exposure R -4 4}
137 | ex {{he2}}
138 | addUserKnob {7 pv l pivot R -4 4}
139 | pv {{hp2}}
140 | addUserKnob {7 fa l falloff}
141 | fa {{hf2}}
142 | addUserKnob {7 f R 0 4}
143 | f {{5*pow(fa,1.6)+1}}
144 | addUserKnob {7 p R 0 10}
145 | p {{fabs(ex+f)<1e-8?1e-8:(ex+f)/f}}
146 | addUserKnob {7 _m R 0 10}
147 | _m {{pow(2,ex)}}
148 | addUserKnob {7 t0}
149 | t0 {{0.18*pow(2,pv)}}
150 | addUserKnob {7 _a R -10 10}
151 | _a {{pow(t0,1-p)/p}}
152 | addUserKnob {7 _b R -10 10}
153 | _b {{t0*(1-1/p)}}
154 | addUserKnob {7 x1 R -10 10}
155 | x1 {{t0*pow(2,f)}}
156 | addUserKnob {7 y1 R -10 10}
157 | y1 {{_a*pow(x1,p)+_b}}
158 | }
159 | Expression {
160 | temp_name0 m
161 | temp_expr0 max(r,g,b)
162 | temp_name1 s
163 | temp_expr1 m>t0?1:pow(m,p)*(_a*m+_b)+_c
164 | expr0 r*s
165 | expr1 g*s
166 | expr2 b*s
167 | name exp_low
168 | xpos -260
169 | ypos 38
170 | addUserKnob {20 Params}
171 | addUserKnob {7 ex l exposure R -4 4}
172 | ex {{le}}
173 | addUserKnob {7 pv l pivot R -3 3}
174 | pv {{lp}}
175 | addUserKnob {7 fa l falloff}
176 | fa {{lf}}
177 | addUserKnob {7 f}
178 | f {{6-5*fa}}
179 | addUserKnob {7 p R 0 10}
180 | p {{min(f/2,f/2*pow(0.5,ex))}}
181 | addUserKnob {7 t0}
182 | t0 {{0.18*pow(2,pv)}}
183 | addUserKnob {7 _a R -10 10}
184 | _a {{p*(_c-1)/(t0**(p+1))}}
185 | addUserKnob {7 _b R -10 10}
186 | _b {{(1-_c)*(p+1)/(t0**p)}}
187 | addUserKnob {7 _c R 0 10}
188 | _c {{pow(2,ex)}}
189 | }
190 | Expression {
191 | temp_name0 m
192 | temp_expr0 max(r,g,b)
193 | temp_name1 s
194 | temp_expr1 m>t0?1:pow(m,p)*(_a*m+_b)+_c
195 | expr0 r*s
196 | expr1 g*s
197 | expr2 b*s
198 | name exp_lower
199 | xpos -260
200 | ypos 62
201 | addUserKnob {20 Params}
202 | addUserKnob {7 ex l exposure R -4 4}
203 | ex {{le2}}
204 | addUserKnob {7 pv l pivot R -3 3}
205 | pv {{lp2}}
206 | addUserKnob {7 fa l falloff}
207 | fa {{lf2}}
208 | addUserKnob {7 f}
209 | f {{6-5*fa}}
210 | addUserKnob {7 p R 0 10}
211 | p {{min(f/2,f/2*pow(0.5,ex))}}
212 | addUserKnob {7 t0}
213 | t0 {{0.18*pow(2,pv)}}
214 | addUserKnob {7 _a R -10 10}
215 | _a {{p*(_c-1)/(t0**(p+1))}}
216 | addUserKnob {7 _b R -10 10}
217 | _b {{(1-_c)*(p+1)/(t0**p)}}
218 | addUserKnob {7 _c R 0 10}
219 | _c {{pow(2,ex)}}
220 | }
221 | push $Nd7e1600
222 | NodeWrapper {
223 | inputs 2+1
224 | channels rgb
225 | name NodeWrapper
226 | xpos -150
227 | ypos 62
228 | }
229 | Output {
230 | name Output
231 | xpos -260
232 | ypos 134
233 | }
234 | end_group
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/n6ChromaValue.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name n6ChromaValue
5 | tile_color 0x536177ff
6 | addUserKnob {20 n6ChromaValue_tab l n6ChromaValue}
7 | addUserKnob {26 about_label l " " T "\n\nNotorious Six Chroma Value created by Jed Smith\n
v0.1.0 | documentation
"}
8 | addUserKnob {41 my l yellow T MultiplyCMY.my}
9 | addUserKnob {41 mr l red T MultiplyRGB.mr}
10 | addUserKnob {41 mm l magenta T MultiplyCMY.mm}
11 | addUserKnob {41 mb l blue T MultiplyRGB.mb}
12 | addUserKnob {41 mc l cyan T MultiplyCMY.mc}
13 | addUserKnob {41 mg l green T MultiplyRGB.mg}
14 | addUserKnob {41 hs_rgb l "hue strength rgb" t "Adjust falloff from center of hue slice." T MultiplyRGB.hs_rgb}
15 | addUserKnob {41 hs_cmy l "hue strength cmy" t "Adjust falloff from center of hue slice." T MultiplyCMY.hs_cmy}
16 | addUserKnob {26 chroma_lbl l " " T chroma}
17 | addUserKnob {41 chs l "chroma strength" t "How much to affect mid-range purity" T ChromaFactor.chs}
18 | addUserKnob {41 chl l "chroma limit" t "Reduce effect at maximal purity" T ChromaFactor.chl}
19 | addUserKnob {6 ze l zoned t "enable zone limiting." +STARTLINE}
20 | addUserKnob {83 zr l "" -STARTLINE M {low high}}
21 | zr high
22 | addUserKnob {7 zp l "zone range" t "set range affected: higher values affect a larger range" R -4 4}
23 | addUserKnob {41 invert T MultiplyMix.invert}
24 | addUserKnob {26 ""}
25 | addUserKnob {41 maskChannelMask l mask -STARTLINE T NodeWrapper1.maskChannelMask}
26 | addUserKnob {41 invert_mask l invert -STARTLINE T NodeWrapper1.invert_mask}
27 | addUserKnob {41 mix T NodeWrapper1.mix}
28 | }
29 | Input {
30 | inputs 0
31 | name Inputmask
32 | xpos 70
33 | ypos 614
34 | number 1
35 | }
36 | Input {
37 | inputs 0
38 | name Input
39 | xpos -40
40 | ypos 278
41 | }
42 | Dot {
43 | name Dot1
44 | xpos -6
45 | ypos 330
46 | }
47 | set N22c03760 [stack 0]
48 | Dot {
49 | name Dot2
50 | xpos 104
51 | ypos 522
52 | }
53 | set N1758e800 [stack 0]
54 | Expression {
55 | temp_name0 n
56 | temp_expr0 max(1e-12,max(r,g,b))
57 | temp_name1 to
58 | temp_expr1 (n*n/(n+fl))
59 | temp_name2 flow
60 | temp_expr2 pow((to/(to+1))/n,p)
61 | temp_name3 fhi
62 | temp_expr3 1-pow((n/(n+1))/n,p)
63 | channel0 {rgba.red -rgba.green -rgba.blue none}
64 | expr0 r
65 | expr1 g
66 | expr2 b
67 | expr3 zr?fhi:flow
68 | name Extract
69 | xpos 70
70 | ypos 566
71 | addUserKnob {20 Params}
72 | addUserKnob {7 fl R 0 0.02}
73 | fl 0.01
74 | addUserKnob {7 p R 0 64}
75 | p {{pow(2,-zp+1)}}
76 | }
77 | push $N22c03760
78 | Dot {
79 | name Dot6
80 | xpos -226
81 | ypos 330
82 | }
83 | Expression {
84 | temp_name0 M
85 | temp_expr0 max(r,g,b)
86 | temp_name1 C
87 | temp_expr1 M-min(r,g,b)
88 | channel0 {rgba.red rgba.green rgba.blue none}
89 | expr0 (C==0?0:r==M?((g-b)/C+6)%6:g==M?(b-r)/C+2:b==M?(r-g)/C+4:0)
90 | expr3 M<=0?0:C/M
91 | name hue
92 | xpos -260
93 | ypos 350
94 | }
95 | set N17585100 [stack 0]
96 | Expression {
97 | temp_name0 h0
98 | temp_expr0 (r+o0)%6
99 | temp_name1 h1
100 | temp_expr1 (r+o1)%6
101 | temp_name2 h2
102 | temp_expr2 (r+o2)%6
103 | expr0 clamp(h0>c0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))
104 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))
105 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))
106 | channel3 none
107 | name LinearWindow1
108 | label CMY
109 | xpos -260
110 | ypos 392
111 | addUserKnob {20 Param}
112 | addUserKnob {7 o0 R 0 6}
113 | o0 5
114 | addUserKnob {7 o1 R 0 6}
115 | o1 3
116 | addUserKnob {7 o2 R 0 6}
117 | o2 1
118 | addUserKnob {26 ""}
119 | addUserKnob {7 c0 R 1 3}
120 | c0 2
121 | addUserKnob {7 f0 R 0.2 1.2}
122 | f0 1
123 | addUserKnob {7 c1 R 1 3}
124 | c1 2
125 | addUserKnob {7 f1 R 0.2 1.2}
126 | f1 1
127 | addUserKnob {7 c2 R 1 3}
128 | c2 2
129 | addUserKnob {7 f2 R 0.2 1.2}
130 | f2 1
131 | }
132 | Expression {
133 | temp_name0 pr
134 | temp_expr0 1-pow(1-r,p.r)
135 | temp_name1 pg
136 | temp_expr1 1-pow(1-g,p.g)
137 | temp_name2 pb
138 | temp_expr2 1-pow(1-b,p.b)
139 | channel0 {rgba.red rgba.green rgba.blue none}
140 | expr0 (1-pr+m.r*pr)*(1-pg+m.g*pg)*(1-pb+m.b*pb)
141 | name MultiplyCMY
142 | xpos -260
143 | ypos 446
144 | addUserKnob {20 Params}
145 | addUserKnob {7 mc R -4 4}
146 | addUserKnob {7 mm R -4 4}
147 | addUserKnob {7 my R -4 4}
148 | addUserKnob {18 hs_cmy R 1 4}
149 | hs_cmy 2
150 | addUserKnob {6 hs_cmy_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
151 | addUserKnob {18 m R 0 4}
152 | m {{2**mc} {2**mm} {2**my}}
153 | addUserKnob {6 m_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
154 | addUserKnob {18 p R 0 4}
155 | p {{min(hs_cmy,hs_cmy/m)} {min(hs_cmy,hs_cmy/m)} {min(hs_cmy,hs_cmy/m)}}
156 | addUserKnob {6 p_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
157 | }
158 | push $N17585100
159 | Expression {
160 | temp_name0 h0
161 | temp_expr0 (r+o0)%6
162 | temp_name1 h1
163 | temp_expr1 (r+o1)%6
164 | temp_name2 h2
165 | temp_expr2 (r+o2)%6
166 | expr0 clamp(h0>c0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))
167 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))
168 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))
169 | channel3 none
170 | name LinearWindow
171 | label RGB
172 | xpos -150
173 | ypos 392
174 | addUserKnob {20 Param}
175 | addUserKnob {7 o0 R 0 6}
176 | o0 2
177 | addUserKnob {7 o1 R 0 6}
178 | o1 6
179 | addUserKnob {7 o2 R 0 6}
180 | o2 4
181 | addUserKnob {26 ""}
182 | addUserKnob {7 c0 R 1 3}
183 | c0 2
184 | addUserKnob {7 f0 R 0.2 1.2}
185 | f0 1
186 | addUserKnob {7 c1 R 1 3}
187 | c1 2
188 | addUserKnob {7 f1 R 0.2 1.2}
189 | f1 1
190 | addUserKnob {7 c2 R 1 3}
191 | c2 2
192 | addUserKnob {7 f2 R 0.2 1.2}
193 | f2 1
194 | }
195 | Expression {
196 | temp_name0 pr
197 | temp_expr0 1-pow(1-r,p.r)
198 | temp_name1 pg
199 | temp_expr1 1-pow(1-g,p.g)
200 | temp_name2 pb
201 | temp_expr2 1-pow(1-b,p.b)
202 | channel0 {rgba.red rgba.green rgba.blue none}
203 | expr0 (1-pr+m.r*pr)*(1-pg+m.g*pg)*(1-pb+m.b*pb)
204 | name MultiplyRGB
205 | xpos -150
206 | ypos 446
207 | addUserKnob {20 Params}
208 | addUserKnob {7 mr R -4 4}
209 | addUserKnob {7 mg R -4 4}
210 | addUserKnob {7 mb R -4 4}
211 | addUserKnob {18 hs_rgb R 1 4}
212 | hs_rgb 2
213 | addUserKnob {6 hs_rgb_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
214 | addUserKnob {18 m R 0 4}
215 | m {{2**mr} {2**mg} {2**mb}}
216 | addUserKnob {6 m_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
217 | addUserKnob {18 p R 0 4}
218 | p {{min(hs_rgb,hs_rgb/m)} {min(hs_rgb,hs_rgb/m)} {min(hs_rgb,hs_rgb/m)}}
219 | addUserKnob {6 p_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
220 | }
221 | Merge2 {
222 | inputs 2
223 | operation multiply
224 | bbox B
225 | output rgb
226 | name Merge1
227 | xpos -150
228 | ypos 495
229 | }
230 | Expression {
231 | temp_name0 cs
232 | temp_expr0 min(1,a)**(1/chs)
233 | temp_name1 cl
234 | temp_expr1 cs*pow(1-cs,chl)
235 | temp_name2 m
236 | temp_expr2 max(1,r)
237 | expr3 cl/(cl*(1-m)+m)
238 | name ChromaFactor
239 | xpos -150
240 | ypos 518
241 | addUserKnob {20 User}
242 | addUserKnob {7 chs}
243 | chs 0.5
244 | addUserKnob {7 chl R 0 4}
245 | }
246 | push $N22c03760
247 | MergeExpression {
248 | inputs 2
249 | temp_name0 f
250 | temp_expr0 1-Aa
251 | expr0 invert?r/(Ar*(1-f)+f):Ar*r*(1-f)+r*f
252 | expr1 invert?g/(Ag*(1-f)+f):Ag*g*(1-f)+g*f
253 | expr2 invert?b/(Ab*(1-f)+f):Ab*b*(1-f)+b*f
254 | name MultiplyMix
255 | xpos -40
256 | ypos 518
257 | addUserKnob {20 User}
258 | addUserKnob {6 invert +STARTLINE}
259 | }
260 | MergeExpression {
261 | inputs 2
262 | temp_name0 f
263 | temp_expr0 ze?Aa:1
264 | expr0 Ar*(1-f)+Br*f
265 | expr1 Ag*(1-f)+Bg*f
266 | expr2 Ab*(1-f)+Bb*f
267 | name Mix
268 | xpos -40
269 | ypos 566
270 | }
271 | push $N1758e800
272 | NodeWrapper {
273 | inputs 2+1
274 | channels rgb
275 | name NodeWrapper1
276 | xpos -40
277 | ypos 614
278 | }
279 | Output {
280 | name Output
281 | xpos -40
282 | ypos 662
283 | }
284 | end_group
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/n6CrossTalk.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name n6CrossTalk
5 | addUserKnob {20 n6CrossTalk_tab l n6CrossTalk}
6 | addUserKnob {26 about_label l " " T "\n\nn6CrossTalk created by Jed Smith\n
v0.0.1 | documentation
"}
7 | addUserKnob {20 color_grp l "" +STARTLINE n -2}
8 | addUserKnob {20 rgb_tab l RGB}
9 | addUserKnob {7 rc l "R center" R -1 1}
10 | addUserKnob {7 gc l "G center" R -1 1}
11 | addUserKnob {7 bc l "B center" R -1 1}
12 | addUserKnob {26 ""}
13 | addUserKnob {7 rp l "red power"}
14 | rp 1
15 | addUserKnob {41 r0 l "red 0: Y->M" T ShiftRGB.r0}
16 | addUserKnob {41 r1 l "red 1: Y->M" T ShiftRGB.rb0}
17 | addUserKnob {41 rs l "red scale" T ShiftRGB.s0}
18 | addUserKnob {7 gp l "green power"}
19 | gp 1
20 | addUserKnob {41 g0 l "green 0: C->Y" T ShiftRGB.r1}
21 | addUserKnob {41 g1 l "green 1: C->Y" T ShiftRGB.rb1}
22 | addUserKnob {41 gs l "green scale" T ShiftRGB.s1}
23 | addUserKnob {7 bp l "blue power"}
24 | bp 1
25 | addUserKnob {41 b0 l "blue 0: M->C" T ShiftRGB.r2}
26 | addUserKnob {41 b1 l "blue 1: M->C" T ShiftRGB.rb2}
27 | addUserKnob {41 bs l "blue scale" T ShiftRGB.s2}
28 | addUserKnob {20 cmy_tab l CMY}
29 | addUserKnob {7 cc l "C center" R -1 1}
30 | cc 0.25
31 | addUserKnob {7 mc l "M center" R -1 1}
32 | addUserKnob {7 yc l "Y center" R -1 1}
33 | yc -0.25
34 | addUserKnob {26 ""}
35 | addUserKnob {7 cp l "cyan power"}
36 | cp 1
37 | addUserKnob {41 c0 l "cyan 0: G->B" T ShiftCMY.r0}
38 | addUserKnob {41 c1 l "cyan 1: G->B" T ShiftCMY.rb0}
39 | addUserKnob {41 cs l "cyan scale" T ShiftCMY.s0}
40 | addUserKnob {7 mp l "magenta power"}
41 | mp 1
42 | addUserKnob {41 m0 l "magenta 0: R->B" T ShiftCMY.r1}
43 | addUserKnob {41 m1 l "magenta 1: R->B" T ShiftCMY.rb1}
44 | addUserKnob {41 ms l "magenta scale" T ShiftCMY.s1}
45 | addUserKnob {7 yp l "yellow power"}
46 | yp 1
47 | addUserKnob {41 y0 l "yellow 0: G->R" T ShiftCMY.r2}
48 | addUserKnob {41 y1 l "yellow 1: G->R" T ShiftCMY.rb2}
49 | addUserKnob {41 ys l "yellow scale" T ShiftCMY.s2}
50 | addUserKnob {20 endGroup n -3}
51 | }
52 | Input {
53 | inputs 0
54 | name Input
55 | xpos 1060
56 | ypos 566
57 | }
58 | Dot {
59 | name Dot407
60 | xpos 1094
61 | ypos 618
62 | }
63 | set N7f8ced00 [stack 0]
64 | Expression {
65 | channel0 rgba
66 | expr0 min(r,g,b)*(1-f)+max(r,g,b)*f
67 | name HCH
68 | xpos 1170
69 | ypos 614
70 | addUserKnob {20 Params}
71 | addUserKnob {7 f}
72 | f 0.5
73 | }
74 | Dot {
75 | name Dot410
76 | xpos 1204
77 | ypos 642
78 | }
79 | set N5b75d910 [stack 0]
80 | Dot {
81 | name Dot409
82 | xpos 1204
83 | ypos 834
84 | }
85 | push $N7f8ced00
86 | Expression {
87 | temp_name0 M
88 | temp_expr0 max(r,g,b)
89 | temp_name1 C
90 | temp_expr1 M-min(r,g,b)
91 | channel0 {rgba.red rgba.green rgba.blue none}
92 | expr0 (C==0?0:r==M?((g-b)/C+6)%6:g==M?(b-r)/C+2:b==M?(r-g)/C+4:0)
93 | expr3 M==0?0:C/M
94 | name HueChroma
95 | xpos 950
96 | ypos 614
97 | }
98 | Clamp {
99 | channels alpha
100 | maximum 4
101 | name Clamp1
102 | xpos 950
103 | ypos 640
104 | }
105 | set N633c55e0 [stack 0]
106 | Expression {
107 | temp_name0 h0
108 | temp_expr0 (r+1)%6
109 | temp_name1 h1
110 | temp_expr1 (r+5)%6
111 | temp_name2 h2
112 | temp_expr2 (r+3)%6
113 | expr0 (h0>x1?0:h0>c.0?(1-((h0-c.0)/(x1-c.0))**p0)**p1:h0>x0?(1-((c.0-h0)/(c.0-x0))**p0)**p1:0)*a**(1/p.0)
114 | expr1 (h1>x1?0:h1>c.1?(1-((h1-c.1)/(x1-c.1))**p0)**p1:h1>x0?(1-((c.1-h1)/(c.1-x0))**p0)**p1:0)*a**(1/p.1)
115 | expr2 (h2>x1?0:h2>c.2?(1-((h2-c.2)/(x1-c.2))**p0)**p1:h2>x0?(1-((c.2-h2)/(c.2-x0))**p0)**p1:0)*a**(1/p.2)
116 | name PowerWindowRGB
117 | xpos 840
118 | ypos 686
119 | addUserKnob {20 Params}
120 | addUserKnob {78 c n 3}
121 | c {{1+rc} {1+gc} {1+bc}}
122 | addUserKnob {7 p0 R 1 2}
123 | p0 1.5
124 | addUserKnob {7 p1 R 1 2}
125 | p1 {{p0}}
126 | addUserKnob {7 x0 R 0 2}
127 | addUserKnob {7 x1 R 0 2}
128 | x1 2
129 | addUserKnob {26 ""}
130 | addUserKnob {78 p n 3}
131 | p {{rp} {gp} {bp}}
132 | }
133 | Dot {
134 | name Dot2
135 | xpos 874
136 | ypos 762
137 | }
138 | push $N633c55e0
139 | Expression {
140 | temp_name0 h0
141 | temp_expr0 (r+4)%6
142 | temp_name1 h1
143 | temp_expr1 (r+2)%6
144 | temp_name2 h2
145 | temp_expr2 (r)%6
146 | expr0 (h0>x1?0:h0>c.0?(1-((h0-c.0)/(x1-c.0))**p0)**p1:h0>x0?(1-((c.0-h0)/(c.0-x0))**p0)**p1:0)*a**(1/p.0)
147 | expr1 (h1>x1?0:h1>c.1?(1-((h1-c.1)/(x1-c.1))**p0)**p1:h1>x0?(1-((c.1-h1)/(c.1-x0))**p0)**p1:0)*a**(1/p.1)
148 | expr2 (h2>x1?0:h2>c.2?(1-((h2-c.2)/(x1-c.2))**p0)**p1:h2>x0?(1-((c.2-h2)/(c.2-x0))**p0)**p1:0)*a**(1/p.2)
149 | name PowerWindowCMY
150 | xpos 950
151 | ypos 686
152 | addUserKnob {20 Params}
153 | addUserKnob {78 c n 3}
154 | c {{1+cc} {1+mc} {1+yc}}
155 | addUserKnob {7 p0 R 1 2}
156 | p0 1.5
157 | addUserKnob {7 p1 R 1 2}
158 | p1 {{p0}}
159 | addUserKnob {7 x0 R 0 2}
160 | addUserKnob {7 x1 R 0 2}
161 | x1 2
162 | addUserKnob {26 ""}
163 | addUserKnob {78 p n 3}
164 | p {{cp} {mp} {yp}}
165 | }
166 | Dot {
167 | name Dot1
168 | xpos 984
169 | ypos 714
170 | }
171 | push $N5b75d910
172 | push $N7f8ced00
173 | MergeExpression {
174 | inputs 2
175 | expr0 Ar==0?0:max(-2,Br/Ar)
176 | expr1 Ag==0?0:max(-2,Bg/Ag)
177 | expr2 Ab==0?0:max(-2,Bb/Ab)
178 | name MergeDivideReverse
179 | xpos 1060
180 | ypos 638
181 | }
182 | MergeExpression {
183 | inputs 2
184 | expr0 (s1+1)*(r-max(0,r1)-min(0,rb1))*Ag+(s2+1)*(r+min(0,r2)+max(0,rb2))*Ab+r*(1-(Ag+Ab))
185 | expr1 (s0+1)*(g-max(0,r0)-min(0,rb0))*Ar+(s2+1)*(g-max(0,r2)-min(0,rb2))*Ab+g*(1-(Ar+Ab))
186 | expr2 (s0+1)*(b+min(0,r0)+max(0,rb0))*Ar+(s1+1)*(b+min(0,r1)+max(0,rb1))*Ag+b*(1-(Ar+Ag))
187 | name ShiftCMY
188 | xpos 1060
189 | ypos 710
190 | addUserKnob {20 Params}
191 | addUserKnob {7 r0 R -1 1}
192 | addUserKnob {7 r1 R -1 1}
193 | addUserKnob {7 r2 R -1 1}
194 | addUserKnob {7 rb0 R -1 1}
195 | addUserKnob {7 rb1 R -1 1}
196 | addUserKnob {7 rb2 R -1 1}
197 | addUserKnob {26 ""}
198 | addUserKnob {7 s0 R -1 1}
199 | addUserKnob {7 s1 R -1 1}
200 | addUserKnob {7 s2 R -1 1}
201 | }
202 | MergeExpression {
203 | inputs 2
204 | expr0 (s0+1)*r*Ar+r*(1+min(0,r1))*(1+max(0,rb1))*Ag+r*(1-max(0,r2))*(1-min(0,rb2))*Ab+r*(1-(Ar+Ag+Ab))
205 | expr1 (s1+1)*g*Ag+g*(1-max(0,r0))*(1-min(0,rb0))*Ar+g*(1+min(0,r2))*(1+max(0,rb2))*Ab+g*(1-(Ar+Ag+Ab))
206 | expr2 (s2+1)*b*Ab+b*(1+min(0,r0))*(1+max(0,rb0))*Ar+b*(1-max(0,r1))*(1-min(0,rb1))*Ag+b*(1-(Ar+Ag+Ab))
207 | name ShiftRGB
208 | xpos 1060
209 | ypos 758
210 | addUserKnob {20 Params}
211 | addUserKnob {7 r0 R -1 1}
212 | addUserKnob {7 r1 R -1 1}
213 | addUserKnob {7 r2 R -1 1}
214 | addUserKnob {7 rb0 R -1 1}
215 | addUserKnob {7 rb1 R -1 1}
216 | addUserKnob {7 rb2 R -1 1}
217 | addUserKnob {26 ""}
218 | addUserKnob {7 s0 R -1 1}
219 | addUserKnob {7 s1 R -1 1}
220 | addUserKnob {7 s2 R -1 1}
221 | }
222 | Merge2 {
223 | inputs 2
224 | operation multiply
225 | bbox B
226 | name MergeMultiply
227 | xpos 1060
228 | ypos 830
229 | }
230 | Output {
231 | name Output
232 | xpos 1060
233 | ypos 902
234 | }
235 | end_group
236 |
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/n6HueShift.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name N6HueShift
5 | tile_color 0x53617700
6 | addUserKnob {20 HueShift_tab l HueShift}
7 | addUserKnob {26 about_label l " " T "\n\nNotorious Six HueShift created by Jed Smith\n
v0.0.4 | documentation
"}
8 | addUserKnob {26 ""}
9 | addUserKnob {7 sy l yellow R -1 1}
10 | addUserKnob {7 sr l red R -1 1}
11 | addUserKnob {7 sm l magenta R -1 1}
12 | addUserKnob {7 sb l blue R -1 1}
13 | addUserKnob {7 sc l cyan R -1 1}
14 | addUserKnob {7 sg l green R -1 1}
15 | addUserKnob {7 scu l custom R -1 1}
16 | addUserKnob {7 cuh l "custom hue" t "hue angle center for custom hue extraction. 0 is green." R 0 360}
17 | cuh 100
18 | addUserKnob {7 cuw l "custom width" t "width for custom hue angle extraction"}
19 | cuw 0.3
20 | addUserKnob {26 ""}
21 | addUserKnob {7 str l strength R 0.1 1}
22 | str 0.33
23 | addUserKnob {7 chl l "chroma limit"}
24 | chl 0.33
25 | addUserKnob {6 ze l "zone extract" t "effect a limited range of luminance." +STARTLINE}
26 | addUserKnob {4 zr l "" -STARTLINE M {low high ""}}
27 | zr 1
28 | addUserKnob {7 zp l "zone range" t "set range affected: higher values affect a larger range" R -4 4}
29 | addUserKnob {26 ""}
30 | addUserKnob {41 maskChannelMask l mask -STARTLINE T NodeWrapper1.maskChannelMask}
31 | addUserKnob {41 invert_mask l invert -STARTLINE T NodeWrapper1.invert_mask}
32 | addUserKnob {41 mix T NodeWrapper1.mix}
33 | }
34 | Input {
35 | inputs 0
36 | name Inputmask
37 | xpos -150
38 | ypos 278
39 | number 1
40 | }
41 | Input {
42 | inputs 0
43 | name Input
44 | xpos -260
45 | ypos -442
46 | }
47 | Dot {
48 | name Dot104
49 | xpos -226
50 | ypos -366
51 | }
52 | set N6ff09600 [stack 0]
53 | Dot {
54 | name Dot1
55 | xpos -336
56 | ypos -366
57 | }
58 | set N6ff08f00 [stack 0]
59 | Dot {
60 | name Dot105
61 | xpos -446
62 | ypos -366
63 | }
64 | Expression {
65 | channel0 rgba
66 | expr0 max(r,g,b)
67 | channel3 none
68 | name Norm
69 | xpos -480
70 | ypos -346
71 | }
72 | Dot {
73 | name Dot2
74 | xpos -446
75 | ypos -318
76 | }
77 | set Nbcffb900 [stack 0]
78 | Dot {
79 | name Dot106
80 | xpos -446
81 | ypos 162
82 | }
83 | set Nbcffb200 [stack 0]
84 | push $N6ff08f00
85 | Dot {
86 | name Dot4
87 | xpos -336
88 | ypos 114
89 | }
90 | set Nbcffab00 [stack 0]
91 | MergeExpression {
92 | inputs 2
93 | temp_name0 n
94 | temp_expr0 max(1e-12,Ar)
95 | temp_name1 to
96 | temp_expr1 (n*n/(n+fl))
97 | temp_name2 flow
98 | temp_expr2 pow((to/(to+1))/n,p)
99 | temp_name3 fhi
100 | temp_expr3 1-pow((n/(n+1))/n,p)
101 | channel0 {rgba.red -rgba.green -rgba.blue none}
102 | expr0 r
103 | expr1 g
104 | expr2 b
105 | expr3 zr?fhi:flow
106 | name Extract2
107 | xpos -370
108 | ypos 206
109 | addUserKnob {20 Params}
110 | addUserKnob {7 fl R 0 0.02}
111 | fl 0.004
112 | addUserKnob {7 p R 0 64}
113 | p {{pow(2,-zp)}}
114 | }
115 | push $Nbcffb200
116 | push $Nbcffb900
117 | push $N6ff09600
118 | MergeExpression {
119 | inputs 2
120 | temp_name0 n
121 | temp_expr0 Ar
122 | expr0 n==0?0:r/n
123 | expr1 n==0?0:g/n
124 | expr2 n==0?0:b/n
125 | name RGBRatios
126 | xpos -260
127 | ypos -322
128 | }
129 | Expression {
130 | temp_name0 th
131 | temp_expr0 -1
132 | expr0 max(th,r)
133 | expr1 max(th,g)
134 | expr2 max(th,b)
135 | name ClampMin
136 | xpos -260
137 | ypos -274
138 | }
139 | Dot {
140 | name Dot7
141 | xpos -226
142 | ypos -222
143 | }
144 | set Nbcff8f00 [stack 0]
145 | Dot {
146 | name Dot9
147 | xpos -116
148 | ypos -222
149 | }
150 | set Nbcff8800 [stack 0]
151 | Expression {
152 | temp_name0 ch
153 | temp_expr0 min(r,g,b)*(1-f)+f
154 | temp_name1 c
155 | temp_expr1 ch==0?0:min(1,1-min(r/ch,g/ch,b/ch))
156 | temp_name2 cl
157 | temp_expr2 chl<0.5?c*f0+c*(1-c)*(1-f0):c*pow(1-c,f0)
158 | channel0 rgba
159 | expr0 cl
160 | name hch
161 | xpos -150
162 | ypos -178
163 | addUserKnob {20 Params}
164 | addUserKnob {7 f}
165 | f {{str}}
166 | addUserKnob {7 f0 R 0 10}
167 | f0 {{chl<0.5?max(0,0.5-chl)*2:1/max(1e-3,((1-chl)*2))}}
168 | }
169 | set Nbcff8100 [stack 0]
170 | push $Nbcff8800
171 | Dot {
172 | name Dot3
173 | xpos 214
174 | ypos -222
175 | }
176 | Expression {
177 | temp_name0 M
178 | temp_expr0 max(r,g,b)
179 | temp_name1 C
180 | temp_expr1 M-min(r,g,b)
181 | channel0 rgba
182 | expr0 (C==0?0:r==M?((g-b)/C+6)%6:g==M?(b-r)/C+2:b==M?(r-g)/C+4:0)
183 | name hue
184 | xpos 180
185 | ypos -178
186 | }
187 | Dot {
188 | name Dot8
189 | xpos 214
190 | ypos -102
191 | }
192 | set Nbc7deb00 [stack 0]
193 | Dot {
194 | name Dot5
195 | xpos 214
196 | ypos -30
197 | }
198 | set N7b7a8800 [stack 0]
199 | Dot {
200 | name Dot6
201 | xpos 214
202 | ypos 42
203 | }
204 | Expression {
205 | temp_name0 h
206 | temp_expr0 (r+o)%6
207 | channel0 rgba
208 | expr0 hc0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))
246 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))
247 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))
248 | channel3 none
249 | name LinearWindow1
250 | label CMY
251 | xpos 70
252 | ypos -40
253 | addUserKnob {20 Param}
254 | addUserKnob {7 o0 R 0 6}
255 | o0 5
256 | addUserKnob {7 o1 R 0 6}
257 | o1 3
258 | addUserKnob {7 o2 R 0 6}
259 | o2 1
260 | addUserKnob {26 ""}
261 | addUserKnob {7 c0 R 1 3}
262 | c0 2
263 | addUserKnob {7 f0 R 0.2 1.2}
264 | f0 1
265 | addUserKnob {7 c1 R 1 3}
266 | c1 2
267 | addUserKnob {7 f1 R 0.2 1.2}
268 | f1 1
269 | addUserKnob {7 c2 R 1 3}
270 | c2 2
271 | addUserKnob {7 f2 R 0.2 1.2}
272 | f2 1
273 | }
274 | MergeExpression {
275 | inputs 2
276 | temp_name0 f
277 | temp_expr0 Ar
278 | expr0 r*f
279 | expr1 g*f
280 | expr2 b*f
281 | name Multiply1
282 | xpos -150
283 | ypos -34
284 | }
285 | push $Nbcff8100
286 | push $Nbc7deb00
287 | Expression {
288 | temp_name0 h0
289 | temp_expr0 (r+o0)%6
290 | temp_name1 h1
291 | temp_expr1 (r+o1)%6
292 | temp_name2 h2
293 | temp_expr2 (r+o2)%6
294 | expr0 clamp(h0>c0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))
295 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))
296 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))
297 | channel3 none
298 | name LinearWindow
299 | label RGB
300 | xpos 70
301 | ypos -112
302 | addUserKnob {20 Param}
303 | addUserKnob {7 o0 R 0 6}
304 | o0 2
305 | addUserKnob {7 o1 R 0 6}
306 | o1 6
307 | addUserKnob {7 o2 R 0 6}
308 | o2 4
309 | addUserKnob {26 ""}
310 | addUserKnob {7 c0 R 1 3}
311 | c0 2
312 | addUserKnob {7 f0 R 0.2 1.2}
313 | f0 1
314 | addUserKnob {7 c1 R 1 3}
315 | c1 2
316 | addUserKnob {7 f1 R 0.2 1.2}
317 | f1 1
318 | addUserKnob {7 c2 R 1 3}
319 | c2 2
320 | addUserKnob {7 f2 R 0.2 1.2}
321 | f2 1
322 | }
323 | MergeExpression {
324 | inputs 2
325 | temp_name0 f
326 | temp_expr0 Ar
327 | expr0 r*f
328 | expr1 g*f
329 | expr2 b*f
330 | name Multiply
331 | xpos -150
332 | ypos -106
333 | }
334 | push $Nbcff8f00
335 | MergeExpression {
336 | inputs 2
337 | expr0 r+Ab*s2-Ag*s1
338 | expr1 g+Ar*s0-Ab*s2
339 | expr2 b+Ag*s1-Ar*s0
340 | name Shift_RGB
341 | xpos -260
342 | ypos -106
343 | addUserKnob {20 Params}
344 | addUserKnob {7 s0 R -1 1}
345 | s0 {{sr}}
346 | addUserKnob {7 s1 R -1 1}
347 | s1 {{sg}}
348 | addUserKnob {7 s2 R -1 1}
349 | s2 {{sb}}
350 | }
351 | MergeExpression {
352 | inputs 2
353 | expr0 r+Ab*s2-Ag*s1
354 | expr1 g+Ar*s0-Ab*s2
355 | expr2 b+Ag*s1-Ar*s0
356 | name Shift_CMY
357 | xpos -260
358 | ypos -34
359 | addUserKnob {20 Params}
360 | addUserKnob {7 s0 R -1 1}
361 | s0 {{sc}}
362 | addUserKnob {7 s1 R -1 1}
363 | s1 {{sm}}
364 | addUserKnob {7 s2 R -1 1}
365 | s2 {{sy}}
366 | }
367 | MergeExpression {
368 | inputs 2
369 | expr0 r+Ar*(sc2-sc1)
370 | expr1 g+Ar*(sc0-sc2)
371 | expr2 b+Ar*(sc1-sc0)
372 | name Shift_Custom
373 | xpos -260
374 | ypos 38
375 | addUserKnob {20 Params}
376 | addUserKnob {7 h R 0 6}
377 | h {{(cuh%360)/60}}
378 | addUserKnob {7 s R -1 1}
379 | s {{scu*cuw}}
380 | addUserKnob {7 sc0 R -1 1}
381 | sc0 {{h<3?s-s*min(1,fabs(h-2)):s*min(1,fabs(h-5))-s}}
382 | addUserKnob {7 sc1 R -1 1}
383 | sc1 {{h<1?s-s*min(1,fabs(h)):h<5?s*min(1,fabs(h-3))-s:s-s*min(1,fabs(h-6))}}
384 | addUserKnob {7 sc2 R -1 1}
385 | sc2 {{h<2?s*min(1,fabs(h-1))-s:s-s*min(1,fabs(h-4))}}
386 | }
387 | MergeExpression {
388 | inputs 2
389 | temp_name0 n
390 | temp_expr0 Ar
391 | expr0 n*r
392 | expr1 n*g
393 | expr2 n*b
394 | name Recombine
395 | xpos -260
396 | ypos 158
397 | }
398 | MergeExpression {
399 | inputs 2
400 | temp_name0 f
401 | temp_expr0 ze?Aa:1
402 | expr0 Ar*(1-f)+Br*f
403 | expr1 Ag*(1-f)+Bg*f
404 | expr2 Ab*(1-f)+Bb*f
405 | name Mix
406 | xpos -260
407 | ypos 206
408 | }
409 | push $Nbcffab00
410 | NodeWrapper {
411 | inputs 2+1
412 | channels rgb
413 | name NodeWrapper1
414 | xpos -260
415 | ypos 278
416 | }
417 | Output {
418 | name Output
419 | xpos -260
420 | ypos 350
421 | }
422 | end_group
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/n6Purity.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name n6Purity
5 | tile_color 0x536177ff
6 | addUserKnob {20 Params_tab l Params}
7 | addUserKnob {26 about_label l " " T "\n\nn6Purity created by Jed Smith\n
v0.0.2 | documentation
"}
8 | addUserKnob {20 color_grp l "" +STARTLINE n -2}
9 | addUserKnob {20 rgb_tab l RGB}
10 | addUserKnob {41 rp l "red purity" T CubicChromaCurveRGB.rp}
11 | addUserKnob {41 rs l "red strength" T CubicChromaCurveRGB.rs}
12 | addUserKnob {41 gp l "green purity" T CubicChromaCurveRGB.gp}
13 | addUserKnob {41 gs l "green strength" T CubicChromaCurveRGB.gs}
14 | addUserKnob {41 bp l "blue purity" T CubicChromaCurveRGB.bp}
15 | addUserKnob {41 bs l "blue strength" T CubicChromaCurveRGB.bs}
16 | addUserKnob {20 cmy_tab l CMY}
17 | addUserKnob {41 cp l "cyan purity" T CubicChromaCurveCMY.cp}
18 | addUserKnob {41 cs l "cyan strength" T CubicChromaCurveCMY.cs}
19 | addUserKnob {41 mp l "magenta purity" T CubicChromaCurveCMY.mp}
20 | addUserKnob {41 ms l "magenta strength" T CubicChromaCurveCMY.ms}
21 | addUserKnob {41 yp l "yellow purity" T CubicChromaCurveCMY.yp}
22 | addUserKnob {41 ys l "yellow strength" T CubicChromaCurveCMY.ys}
23 | addUserKnob {20 endGroup n -3}
24 | }
25 | Input {
26 | inputs 0
27 | name Input
28 | xpos 840
29 | ypos 566
30 | }
31 | Dot {
32 | name Dot425
33 | xpos 874
34 | ypos 642
35 | }
36 | set N63c749a0 [stack 0]
37 | Dot {
38 | name Dot421
39 | xpos 544
40 | ypos 642
41 | }
42 | Expression {
43 | temp_name0 M
44 | temp_expr0 max(r,g,b)
45 | temp_name1 C
46 | temp_expr1 M-min(r,g,b)
47 | channel0 {rgba.red rgba.green rgba.blue none}
48 | expr0 (C==0?0:r==M?((g-b)/C+6)%6:g==M?(b-r)/C+2:b==M?(r-g)/C+4:0)
49 | expr3 M==0?0:C/M
50 | name HueChroma
51 | xpos 510
52 | ypos 662
53 | }
54 | set N6afa7290 [stack 0]
55 | Expression {
56 | temp_name0 h0
57 | temp_expr0 (r+1)%6
58 | temp_name1 h1
59 | temp_expr1 (r+5)%6
60 | temp_name2 h2
61 | temp_expr2 (r+3)%6
62 | expr0 (h0>x1?0:h0>c.0?(1-((h0-c.0)/(x1-c.0))**p0)**p1:h0>x0?(1-((c.0-h0)/(c.0-x0))**p0)**p1:0)
63 | expr1 (h1>x1?0:h1>c.1?(1-((h1-c.1)/(x1-c.1))**p0)**p1:h1>x0?(1-((c.1-h1)/(c.1-x0))**p0)**p1:0)
64 | expr2 (h2>x1?0:h2>c.2?(1-((h2-c.2)/(x1-c.2))**p0)**p1:h2>x0?(1-((c.2-h2)/(c.2-x0))**p0)**p1:0)
65 | name PowerWindowRGB
66 | label https://www.desmos.com/calculator/8tqz4rs0wm
67 | xpos 510
68 | ypos 712
69 | addUserKnob {20 Params}
70 | addUserKnob {78 c n 3}
71 | c {1 1 1}
72 | addUserKnob {7 p0 R 1 2}
73 | p0 2
74 | addUserKnob {7 p1 R 1 2}
75 | p1 2
76 | addUserKnob {7 x0 R 0 2}
77 | addUserKnob {7 x1 R 0 2}
78 | x1 2
79 | }
80 | Expression {
81 | temp_name0 c
82 | temp_expr0 1-a
83 | temp_name1 cr
84 | temp_expr1 a==0?a:(rp<0?a>1?a:a<0?m.0*a:a*(a**p.0*(a0.0*a+b0.0)+m.0):a<0?a:a>1?m.0*(a-1)+1:(1-c*(c**p.0*(a0.0*c+b0.0)+m.0)))/a
85 | temp_name2 cg
86 | temp_expr2 a==0?a:(gp<0?a>1?a:a<0?m.1*a:a*(a**p.1*(a0.1*a+b0.1)+m.1):a<0?a:a>1?m.1*(a-1)+1:(1-c*(c**p.1*(a0.1*c+b0.1)+m.1)))/a
87 | temp_name3 cb
88 | temp_expr3 a==0?a:(bp<0?a>1?a:a<0?m.2*a:a*(a**p.2*(a0.2*a+b0.2)+m.2):a<0?a:a>1?m.2*(a-1)+1:(1-c*(c**p.2*(a0.2*c+b0.2)+m.2)))/a
89 | channel0 rgb
90 | expr0 r*cr+g*cg+b*cb+(1-(r+g+b))
91 | name CubicChromaCurveRGB
92 | label https://www.desmos.com/calculator/bdbstdsvvv
93 | xpos 510
94 | ypos 762
95 | addUserKnob {20 Params}
96 | addUserKnob {7 rp l "red purity" t "adjust mid-range chrominance" R -1 1}
97 | addUserKnob {7 rs l "red strength" t "strength of the adjustment" R 0 4}
98 | rs 2
99 | addUserKnob {7 gp l "green purity" t "adjust mid-range chrominance" R -1 1}
100 | addUserKnob {7 gs l "green strength" t "strength of the adjustment" R 0 4}
101 | gs 2
102 | addUserKnob {7 bp l "blue purity" t "adjust mid-range chrominance" R -1 1}
103 | addUserKnob {7 bs l "blue strength" t "strength of the adjustment" R 0 4}
104 | bs 2
105 | addUserKnob {78 m R -1 1 n 3}
106 | m {{1-fabs(rp)} {1-fabs(gp)} {1-fabs(bp)}}
107 | addUserKnob {78 p R 0 10 n 3}
108 | p {{rs} {gs} {bs}}
109 | addUserKnob {78 a0 R -10 10 n 3}
110 | a0 {{p*(m-1)} {p*(m-1)} {p*(m-1)}}
111 | addUserKnob {78 b0 R -10 10 n 3}
112 | b0 {{(1-m)*(p+1)} {(1-m)*(p+1)} {(1-m)*(p+1)}}
113 | }
114 | push $N6afa7290
115 | Expression {
116 | temp_name0 h0
117 | temp_expr0 (r+4)%6
118 | temp_name1 h1
119 | temp_expr1 (r+2)%6
120 | temp_name2 h2
121 | temp_expr2 (r)%6
122 | expr0 (h0>x1?0:h0>c.0?(1-((h0-c.0)/(x1-c.0))**p0)**p1:h0>x0?(1-((c.0-h0)/(c.0-x0))**p0)**p1:0)
123 | expr1 (h1>x1?0:h1>c.1?(1-((h1-c.1)/(x1-c.1))**p0)**p1:h1>x0?(1-((c.1-h1)/(c.1-x0))**p0)**p1:0)
124 | expr2 (h2>x1?0:h2>c.2?(1-((h2-c.2)/(x1-c.2))**p0)**p1:h2>x0?(1-((c.2-h2)/(c.2-x0))**p0)**p1:0)
125 | name PowerWindowCMY
126 | xpos 620
127 | ypos 710
128 | addUserKnob {20 Params}
129 | addUserKnob {78 c n 3}
130 | c {1 1 1}
131 | addUserKnob {7 p0 R 1 2}
132 | p0 2
133 | addUserKnob {7 p1 R 1 2}
134 | p1 2
135 | addUserKnob {7 x0 R 0 2}
136 | addUserKnob {7 x1 R 0 2}
137 | x1 2
138 | }
139 | Expression {
140 | temp_name0 c
141 | temp_expr0 1-a
142 | temp_name1 cr
143 | temp_expr1 a==0?a:(cp<0?a>1?a:a<0?m.0*a:a*(a**p.0*(a0.0*a+b0.0)+m.0):a<0?a:a>1?m.0*(a-1)+1:(1-c*(c**p.0*(a0.0*c+b0.0)+m.0)))/a
144 | temp_name2 cg
145 | temp_expr2 a==0?a:(mp<0?a>1?a:a<0?m.1*a:a*(a**p.1*(a0.1*a+b0.1)+m.1):a<0?a:a>1?m.1*(a-1)+1:(1-c*(c**p.1*(a0.1*c+b0.1)+m.1)))/a
146 | temp_name3 cb
147 | temp_expr3 a==0?a:(yp<0?a>1?a:a<0?m.2*a:a*(a**p.2*(a0.2*a+b0.2)+m.2):a<0?a:a>1?m.2*(a-1)+1:(1-c*(c**p.2*(a0.2*c+b0.2)+m.2)))/a
148 | channel0 rgb
149 | expr0 r*cr+g*cg+b*cb+(1-(r+g+b))
150 | name CubicChromaCurveCMY
151 | xpos 620
152 | ypos 748
153 | addUserKnob {20 Params}
154 | addUserKnob {7 cp l "cyan purity" t "adjust mid-range chrominance" R -1 1}
155 | addUserKnob {7 cs l "cyan strength" t "strength of the adjustment" R 0 4}
156 | cs 2
157 | addUserKnob {7 mp l "magenta purity" t "adjust mid-range chrominance" R -1 1}
158 | addUserKnob {7 ms l "magenta strength" t "strength of the adjustment" R 0 4}
159 | ms 2
160 | addUserKnob {7 yp l "yellow purity" t "adjust mid-range chrominance" R -1 1}
161 | addUserKnob {7 ys l "yellow strength" t "strength of the adjustment" R 0 4}
162 | ys 2
163 | addUserKnob {78 m R -1 1 n 3}
164 | m {{1-fabs(cp)} {1-fabs(mp)} {1-fabs(yp)}}
165 | addUserKnob {78 p R 0 10 n 3}
166 | p {{cs} {ms} {ys}}
167 | addUserKnob {78 a0 R -10 10 n 3}
168 | a0 {{p*(m-1)} {p*(m-1)} {p*(m-1)}}
169 | addUserKnob {78 b0 R -10 10 n 3}
170 | b0 {{(1-m)*(p+1)} {(1-m)*(p+1)} {(1-m)*(p+1)}}
171 | }
172 | Merge2 {
173 | inputs 2
174 | operation multiply
175 | bbox B
176 | name Merge162
177 | xpos 510
178 | ypos 806
179 | }
180 | push $N63c749a0
181 | Dot {
182 | name Dot299
183 | xpos 874
184 | ypos 738
185 | }
186 | set N67b039a0 [stack 0]
187 | Expression {
188 | channel0 rgba
189 | expr0 r*rw+g*gw+b*bw
190 | name Weights
191 | label "Weighted Sum"
192 | xpos 730
193 | ypos 728
194 | addUserKnob {20 User}
195 | addUserKnob {7 rw R 0.05 0.6}
196 | rw 0.3
197 | addUserKnob {7 gw}
198 | gw {{1-(rw+bw)}}
199 | addUserKnob {7 bw R 0.05 0.6}
200 | bw 0.1
201 | }
202 | Copy {
203 | inputs 2
204 | from0 rgba.red
205 | to0 rgba.alpha
206 | name Copy16
207 | xpos 730
208 | ypos 800
209 | }
210 | push $N67b039a0
211 | MergeExpression {
212 | inputs 2
213 | temp_name0 f
214 | temp_expr0 Aa
215 | temp_name1 L
216 | temp_expr1 Ar
217 | expr0 L*(1-f)+r*f
218 | expr1 L*(1-f)+g*f
219 | expr2 L*(1-f)+b*f
220 | name ChromaLerp
221 | xpos 840
222 | ypos 806
223 | }
224 | Output {
225 | name Output
226 | xpos 840
227 | ypos 878
228 | }
229 | end_group
230 |
--------------------------------------------------------------------------------
/look-transforms/tools/nuke/n6Vibrance.nk:
--------------------------------------------------------------------------------
1 | set cut_paste_input [stack 0]
2 | push $cut_paste_input
3 | Group {
4 | name N6Vibrance
5 | tile_color 0x536177ff
6 | addUserKnob {20 Vibrance_tab l Vibrance}
7 | addUserKnob {26 about_label l " " T "\n\nNotorious Six Vibrance created by Jed Smith\n
v0.0.3 | documentation
"}
8 | addUserKnob {7 mgl l global R -1 1}
9 | addUserKnob {7 my l yellow R -1 1}
10 | addUserKnob {7 mr l red R -1 1}
11 | addUserKnob {7 mm l magenta R -1 1}
12 | addUserKnob {7 mb l blue R -1 1}
13 | addUserKnob {7 mc l cyan R -1 1}
14 | addUserKnob {7 mg l green R -1 1}
15 | addUserKnob {7 mcu l custom R -1 1}
16 | addUserKnob {7 cuh l "custom hue" t "hue angle center for custom hue extraction. 0 is green." R 0 360}
17 | cuh 100
18 | addUserKnob {7 cuw l "custom width" t "width for custom hue angle extraction"}
19 | cuw 0.3
20 | addUserKnob {26 ""}
21 | addUserKnob {7 hl l hue-linear}
22 | hl 0.5
23 | addUserKnob {6 ze l "zone extract" t "effect a limited range of luminance." +STARTLINE}
24 | ze true
25 | addUserKnob {4 zr l "" -STARTLINE M {low high ""}}
26 | addUserKnob {7 zp l "zone range" t "set range affected: higher values affect a larger range" R -4 4}
27 | addUserKnob {26 ""}
28 | addUserKnob {41 maskChannelMask l mask -STARTLINE T NodeWrapper1.maskChannelMask}
29 | addUserKnob {41 invert_mask l invert -STARTLINE T NodeWrapper1.invert_mask}
30 | addUserKnob {41 mix T NodeWrapper1.mix}
31 | }
32 | Input {
33 | inputs 0
34 | name Inputmask
35 | xpos 290
36 | ypos 230
37 | number 1
38 | }
39 | Input {
40 | inputs 0
41 | name Input
42 | xpos 180
43 | ypos -322
44 | }
45 | Dot {
46 | name Dot104
47 | xpos 214
48 | ypos -270
49 | }
50 | set Na64fcf00 [stack 0]
51 | Dot {
52 | name Dot24
53 | xpos 104
54 | ypos -270
55 | }
56 | set Na64fc800 [stack 0]
57 | Dot {
58 | name Dot105
59 | xpos -6
60 | ypos -270
61 | }
62 | Expression {
63 | channel0 rgba
64 | expr0 max(r,g,b)
65 | channel3 none
66 | name Norm
67 | xpos -40
68 | ypos -250
69 | }
70 | Dot {
71 | name Dot21
72 | xpos -6
73 | ypos -198
74 | }
75 | set Na2713200 [stack 0]
76 | Dot {
77 | name Dot106
78 | xpos -6
79 | ypos 114
80 | }
81 | set Na2712b00 [stack 0]
82 | push $Na64fc800
83 | Dot {
84 | name Dot27
85 | xpos 104
86 | ypos 66
87 | }
88 | set Na2712400 [stack 0]
89 | MergeExpression {
90 | inputs 2
91 | temp_name0 n
92 | temp_expr0 max(1e-12,Ar)
93 | temp_name1 to
94 | temp_expr1 (n*n/(n+fl))
95 | temp_name2 flow
96 | temp_expr2 pow((to/(to+1))/n,p)
97 | temp_name3 fhi
98 | temp_expr3 1-pow((n/(n+1))/n,p)
99 | channel0 {rgba.red -rgba.green -rgba.blue none}
100 | expr0 r
101 | expr1 g
102 | expr2 b
103 | expr3 zr?fhi:flow
104 | name Extract
105 | xpos 70
106 | ypos 158
107 | addUserKnob {20 Params}
108 | addUserKnob {7 fl R 0 0.02}
109 | fl 0.004
110 | addUserKnob {7 p R 0 64}
111 | p {{pow(2,-zp)}}
112 | }
113 | push $Na2712b00
114 | push $Na2713200
115 | push $Na64fcf00
116 | MergeExpression {
117 | inputs 2
118 | temp_name0 n
119 | temp_expr0 Ar
120 | temp_name1 mn
121 | temp_expr1 -1
122 | expr0 n==0?0:max(mn,r/n)
123 | expr1 n==0?0:max(mn,g/n)
124 | expr2 n==0?0:max(mn,b/n)
125 | name RGBRatios
126 | xpos 180
127 | ypos -202
128 | }
129 | Dot {
130 | name Dot4
131 | xpos 214
132 | ypos -150
133 | }
134 | set Na2710f00 [stack 0]
135 | Expression {
136 | temp_name0 C
137 | temp_expr0 1-min(r,g,b)
138 | channel0 {rgba.red rgba.green rgba.blue none}
139 | expr0 (C==0?0:r==1?((g-b)/C+6)%6:g==1?(b-r)/C+2:b==1?(r-g)/C+4:0)
140 | expr3 C
141 | name hue
142 | xpos 510
143 | ypos -154
144 | }
145 | Dot {
146 | name Dot5
147 | xpos 544
148 | ypos -102
149 | }
150 | set Na2710100 [stack 0]
151 | Dot {
152 | name Dot6
153 | xpos 544
154 | ypos -54
155 | }
156 | set Na6f63900 [stack 0]
157 | Dot {
158 | name Dot7
159 | xpos 544
160 | ypos -6
161 | }
162 | Expression {
163 | temp_name0 h
164 | temp_expr0 (r+o)%6
165 | channel0 {rgba.red rgba.green rgba.blue none}
166 | expr0 (hc0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))*a
193 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))*a
194 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))*a
195 | channel3 none
196 | name LerpWindow4
197 | label CMY
198 | xpos 400
199 | ypos -64
200 | addUserKnob {20 Param}
201 | addUserKnob {7 o0 R 0 6}
202 | o0 5
203 | addUserKnob {7 o1 R 0 6}
204 | o1 3
205 | addUserKnob {7 o2 R 0 6}
206 | o2 1
207 | addUserKnob {26 ""}
208 | addUserKnob {7 c0 R 1 3}
209 | c0 2
210 | addUserKnob {7 f0 R 0.2 1.2}
211 | f0 1
212 | addUserKnob {7 c1 R 1 3}
213 | c1 2
214 | addUserKnob {7 f1 R 0.2 1.2}
215 | f1 1
216 | addUserKnob {7 c2 R 1 3}
217 | c2 2
218 | addUserKnob {7 f2 R 0.2 1.2}
219 | f2 1
220 | }
221 | set Na6f62400 [stack 0]
222 | push $Na2710100
223 | Expression {
224 | temp_name0 h0
225 | temp_expr0 (r+o0)%6
226 | temp_name1 h1
227 | temp_expr1 (r+o1)%6
228 | temp_name2 h2
229 | temp_expr2 (r+o2)%6
230 | expr0 clamp(h0>c0?(h0-c0-f0)/(c0-(c0+f0)):(h0-(c0-f0))/(c0-(c0-f0)))*a
231 | expr1 clamp(h1>c1?(h1-c1-f1)/(c1-(c1+f1)):(h1-(c1-f1))/(c1-(c1-f1)))*a
232 | expr2 clamp(h2>c2?(h2-c2-f2)/(c2-(c2+f2)):(h2-(c2-f2))/(c2-(c2-f2)))*a
233 | channel3 none
234 | name LerpWindow2
235 | label RGB
236 | xpos 400
237 | ypos -112
238 | addUserKnob {20 Param}
239 | addUserKnob {7 o0 R 0 6}
240 | o0 2
241 | addUserKnob {7 o1 R 0 6}
242 | o1 6
243 | addUserKnob {7 o2 R 0 6}
244 | o2 4
245 | addUserKnob {26 ""}
246 | addUserKnob {7 c0 R 1 3}
247 | c0 2
248 | addUserKnob {7 f0 R 0.2 1.2}
249 | f0 1
250 | addUserKnob {7 c1 R 1 3}
251 | c1 2
252 | addUserKnob {7 f1 R 0.2 1.2}
253 | f1 1
254 | addUserKnob {7 c2 R 1 3}
255 | c2 2
256 | addUserKnob {7 f2 R 0.2 1.2}
257 | f2 1
258 | }
259 | set Na6f61d00 [stack 0]
260 | push $Na2710f00
261 | MergeExpression {
262 | inputs 2
263 | temp_name0 m
264 | temp_expr0 1.1
265 | temp_name1 c
266 | temp_expr1 Aa
267 | temp_name3 f
268 | temp_expr3 c==0||c>1?1:((1-pow(1-c,p0))*Ar+(1-pow(1-c,p1))*Ag+(1-pow(1-c,p2))*Ab+c*(1-(Ar+Ag+Ab)))/c
269 | channel0 {rgba.red -rgba.green -rgba.blue none}
270 | expr0 m*(1-f)+r*f
271 | expr1 m*(1-f)+g*f
272 | expr2 m*(1-f)+b*f
273 | expr3 f
274 | name vihl_rgb
275 | xpos 180
276 | ypos -106
277 | addUserKnob {20 Params}
278 | addUserKnob {7 p0 R 0 4}
279 | p0 {{3**mr*3**mgl}}
280 | addUserKnob {7 p1 R 0 4}
281 | p1 {{3**mg*3**mgl}}
282 | addUserKnob {7 p2 R 0 4}
283 | p2 {{3**mb*3**mgl}}
284 | }
285 | MergeExpression {
286 | inputs 2
287 | temp_name0 m
288 | temp_expr0 1
289 | temp_name1 c
290 | temp_expr1 Aa
291 | temp_name3 f
292 | temp_expr3 c==0?1:((1-pow(1-c,p0))*Ar+(1-pow(1-c,p1))*Ag+(1-pow(1-c,p2))*Ab+c*(1-(Ar+Ag+Ab)))/c
293 | channel0 {rgba.red -rgba.green -rgba.blue none}
294 | expr0 m*(1-f)+r*f
295 | expr1 m*(1-f)+g*f
296 | expr2 m*(1-f)+b*f
297 | name vihl_cmy
298 | xpos 180
299 | ypos -58
300 | addUserKnob {20 Params}
301 | addUserKnob {7 p0 R 0 4}
302 | p0 {{3**mc*3**mgl}}
303 | addUserKnob {7 p1 R 0 4}
304 | p1 {{3**mm*3**mgl}}
305 | addUserKnob {7 p2 R 0 4}
306 | p2 {{3**my*2**mgl}}
307 | }
308 | MergeExpression {
309 | inputs 2
310 | temp_name0 m
311 | temp_expr0 1
312 | temp_name1 c
313 | temp_expr1 Aa
314 | temp_name3 f
315 | temp_expr3 c==0?1:((1-pow(1-c,p))*Ar+c*(1-Ar))/c
316 | channel0 {rgba.red -rgba.green -rgba.blue none}
317 | expr0 m*(1-f)+r*f
318 | expr1 m*(1-f)+g*f
319 | expr2 m*(1-f)+b*f
320 | name vihl_cu
321 | xpos 180
322 | ypos -10
323 | addUserKnob {20 Params}
324 | addUserKnob {7 p R 0 4}
325 | p {{3**mcu}}
326 | }
327 | push $Na6f62b00
328 | push $Na6f62400
329 | push $Na6f61d00
330 | push $Na2710f00
331 | MergeExpression {
332 | inputs 2
333 | channel0 {rgba.red -rgba.green -rgba.blue none}
334 | expr0 pow(r,p0)*Ar+pow(r,p1)*Ag+pow(r,p2)*Ab+r*(1-(Ar+Ag+Ab))
335 | expr1 pow(g,p0)*Ar+pow(g,p1)*Ag+pow(g,p2)*Ab+g*(1-(Ar+Ag+Ab))
336 | expr2 pow(b,p0)*Ar+pow(b,p1)*Ag+pow(b,p2)*Ab+b*(1-(Ar+Ag+Ab))
337 | name vi_rgb
338 | xpos 290
339 | ypos -82
340 | addUserKnob {20 Params}
341 | addUserKnob {7 p0 R 0 4}
342 | p0 {{parent.vihl_rgb.p0}}
343 | addUserKnob {7 p1 R 0 4}
344 | p1 {{parent.vihl_rgb.p1}}
345 | addUserKnob {7 p2 R 0 4}
346 | p2 {{parent.vihl_rgb.p2}}
347 | }
348 | MergeExpression {
349 | inputs 2
350 | channel0 {rgba.red -rgba.green -rgba.blue none}
351 | expr0 pow(r,p0)*Ar+pow(r,p1)*Ag+pow(r,p2)*Ab+r*(1-(Ar+Ag+Ab))
352 | expr1 pow(g,p0)*Ar+pow(g,p1)*Ag+pow(g,p2)*Ab+g*(1-(Ar+Ag+Ab))
353 | expr2 pow(b,p0)*Ar+pow(b,p1)*Ag+pow(b,p2)*Ab+b*(1-(Ar+Ag+Ab))
354 | name vi_cmy
355 | xpos 290
356 | ypos -34
357 | addUserKnob {20 Params}
358 | addUserKnob {7 p0 R 0 4}
359 | p0 {{parent.vihl_cmy.p0}}
360 | addUserKnob {7 p1 R 0 4}
361 | p1 {{parent.vihl_cmy.p1}}
362 | addUserKnob {7 p2 R 0 4}
363 | p2 {{parent.vihl_cmy.p2}}
364 | }
365 | MergeExpression {
366 | inputs 2
367 | channel0 {rgba.red -rgba.green -rgba.blue none}
368 | expr0 pow(r,p0)*Ar+r*(1-Ar)
369 | expr1 pow(g,p0)*Ar+g*(1-Ar)
370 | expr2 pow(b,p0)*Ar+b*(1-Ar)
371 | name vi_cu
372 | xpos 290
373 | ypos 17
374 | addUserKnob {20 Params}
375 | addUserKnob {7 p0 R 0 4}
376 | p0 {{parent.vihl_cu.p}}
377 | }
378 | Dissolve {
379 | inputs 2
380 | channels rgb
381 | which {{hl}}
382 | name Mix_hue_linear
383 | xpos 180
384 | ypos 63
385 | }
386 | MergeExpression {
387 | inputs 2
388 | temp_name0 n
389 | temp_expr0 Ar
390 | expr0 n*r
391 | expr1 n*g
392 | expr2 n*b
393 | name Recombine
394 | xpos 180
395 | ypos 110
396 | }
397 | MergeExpression {
398 | inputs 2
399 | temp_name0 f
400 | temp_expr0 ze?Aa:1
401 | expr0 Ar*(1-f)+Br*f
402 | expr1 Ag*(1-f)+Bg*f
403 | expr2 Ab*(1-f)+Bb*f
404 | name Mix
405 | xpos 180
406 | ypos 158
407 | }
408 | push $Na2712400
409 | NodeWrapper {
410 | inputs 2+1
411 | channels rgb
412 | name NodeWrapper1
413 | xpos 180
414 | ypos 230
415 | }
416 | Output {
417 | name Output
418 | xpos 180
419 | ypos 302
420 | }
421 | end_group
422 |
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/HighlightContrast.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(ex, exposure, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
5 | DEFINE_UI_PARAMS(th, threshold, DCTLUI_SLIDER_FLOAT, -1, -4, 4, 0)
6 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
7 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
8 |
9 |
10 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
11 | {
12 | float3 rgb = make_float3(p_R, p_G, p_B);
13 | rgb = linearize(rgb, tf, 0);
14 | rgb = hl_con(rgb, ex, th, invert);
15 | rgb = linearize(rgb, tf, 1);
16 | return rgb;
17 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/HueContrast.dctl:
--------------------------------------------------------------------------------
1 | #line 1 // Fix line numbers in resolve/logs/rollinglog.txt
2 | /* HueContrast -------------------------------------------------
3 | v0.0.3
4 | A tool to compress hues towards the primary color vectors. Pretty similar to n6HueShift
5 | but parameterized to compress or expand on both sides of a primary hue vector instead.
6 |
7 | Written by Jed Smith
8 | https://github.com/jedypod/open-display-transform
9 |
10 | License: GPL v3
11 | -------------------------------------------------*/
12 |
13 |
14 | DEFINE_UI_PARAMS(m0r, focus - R low, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
15 | DEFINE_UI_PARAMS(m1r, R high, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
16 | DEFINE_UI_PARAMS(m0g, G low, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
17 | DEFINE_UI_PARAMS(m1g, G high, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
18 | DEFINE_UI_PARAMS(m0b, B low, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
19 | DEFINE_UI_PARAMS(m1b, B high, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
20 | DEFINE_UI_PARAMS(p_sr, strength - R, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
21 | DEFINE_UI_PARAMS(p_sg, G, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
22 | DEFINE_UI_PARAMS(p_sb, B, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
23 | DEFINE_UI_PARAMS(p_wr, width - R, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
24 | DEFINE_UI_PARAMS(p_wg, G, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
25 | DEFINE_UI_PARAMS(p_wb, B, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
26 | DEFINE_UI_PARAMS(bias, bias, DCTLUI_SLIDER_FLOAT, 0.0, -3.0, 3.0, 0)
27 |
28 |
29 |
30 |
31 | //----------------------------------------------------------------------------//
32 |
33 |
34 | // Safe power function raising float a to power float b
35 | __DEVICE__ float spowf(float a, float b) {
36 | if (a <= 0.0f) return a;
37 | else return _powf(a, b);
38 | }
39 |
40 | // Safe division of float a by float b
41 | __DEVICE__ float sdivf(float a, float b) {
42 | if (b == 0.0f) return 0.0f;
43 | else return a/b;
44 | }
45 |
46 | // Safe division of float3 a by float b
47 | __DEVICE__ float3 sdivf3f(float3 a, float b) {
48 | return make_float3(sdivf(a.x, b), sdivf(a.y, b), sdivf(a.z, b));
49 | }
50 |
51 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
52 | {
53 | // Parameter Setup
54 | float3 m0 = make_float3(1.0f - m0r, 1.0f - m0g, 1.0f - m0b);
55 | float3 m1 = make_float3(1.0f - m1r, 1.0f - m1g, 1.0f - m1b);
56 |
57 | float3 in = make_float3(p_R, p_G, p_B);
58 |
59 | // RGB Ratios
60 | float mx = _fmaxf(in.x, _fmaxf(in.y, in.z));
61 | mx = _fabs(mx) < 1e-4f ? 0.0f : mx;
62 | float3 rgb = sdivf3f(in, mx);
63 | float mn = _fmaxf(0.0f, _fminf(rgb.x, _fminf(rgb.y, rgb.z)));
64 |
65 | // Remove achromatic from RGB Ratios
66 | rgb = rgb - mn;
67 |
68 | // Mix between wide and narrow hue angles
69 | rgb = make_float3( _fminf(1.0f, _fmaxf(0.0f, rgb.x - (rgb.y + rgb.z)*(1.0f - p_wr))),
70 | _fminf(1.0f, _fmaxf(0.0f, rgb.y - (rgb.x + rgb.z)*(1.0f - p_wg))),
71 | _fminf(1.0f, _fmaxf(0.0f, rgb.z - (rgb.x + rgb.y)*(1.0f - p_wb))));
72 |
73 | // Apply power function to chroma to adjust strength
74 | rgb = make_float3(spowf(rgb.x, 1.0f/p_sr), spowf(rgb.y, 1.0f/p_sg), spowf(rgb.z, 1.0f/p_sb));
75 |
76 |
77 | /* Hue Distortion
78 | We make the hue distortion bidirectional by using a lerp factor based on a generic hyperbolic
79 | "tonescale" curve, biased by a power function w/ lin extension.
80 | We use a Lift/Multiply linear function to remap the input
81 | to the 0-2 range expected by the lerp (1.0 is no distortion, 2.0 is distorted towards the primary,
82 | 0.0 is distorted towards the secondary).
83 | */
84 | // Spliced contrast: https://www.desmos.com/calculator/61ezkjxsgb
85 | const float p = spowf(2.0f, bias);
86 | const float s0 = spowf(0.18, 1.0f - p);
87 | const float t0 = 0.18f;
88 | float zr_f = mx < t0 ? s0*spowf(mx, p) : p*(mx - t0) + t0;
89 |
90 | // Generic hyperbolic compression, roughly aligning middle grey to typical display output value
91 | zr_f = sdivf(zr_f, zr_f + 0.66f);
92 |
93 | // Remap with a lift/multiply function: https://www.desmos.com/calculator/eaxwxrhrev
94 | float3 f = make_float3(zr_f*(m1.x-m0.x)+m0.x, zr_f*(m1.y-m0.y)+m0.y, zr_f*(m1.z-m0.z)+m0.z);
95 |
96 | // Do the hue distortion / compression / "focus", basically a 3-way lerp
97 | rgb = make_float3(
98 | in.x*f.y*rgb.y + in.x*f.z*rgb.z + in.x*(1.0f - (rgb.y + rgb.z)),
99 | in.y*f.x*rgb.x + in.y*f.z*rgb.z + in.y*(1.0f - (rgb.x + rgb.z)),
100 | in.z*f.x*rgb.x + in.z*f.y*rgb.y + in.z*(1.0f - (rgb.x + rgb.y)));
101 |
102 | return rgb;
103 | }
104 |
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/LinearGrade.dctl:
--------------------------------------------------------------------------------
1 | /* Linear Grade
2 | Super simple chromaticity preserving scene-linear grading operator.
3 | offset -> pivoted contrast -> exposure
4 | */
5 |
6 | DEFINE_UI_PARAMS(e, exposure, DCTLUI_SLIDER_FLOAT, 0.0, -6.0, 6.0, 0.0)
7 | DEFINE_UI_PARAMS(c, contrast, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
8 | DEFINE_UI_PARAMS(pv, pivot, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
9 | DEFINE_UI_PARAMS(off, offset, DCTLUI_SLIDER_FLOAT, 0.0, -0.02, 0.02, 0.0)
10 |
11 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
12 | {
13 | float3 rgb = make_float3(p_R, p_G, p_B);
14 | const float ex = _powf(2.0f, e);
15 | rgb += off;
16 | float m = _fmaxf(rgb.x, _fmaxf(rgb.y, rgb.z)) / _powf(2.0f, pv);
17 | float s = c == 1.0f || c <= 0.0f ? ex : m > 0.0f ? _powf(m, c - 1.0f) * ex : 1.0f;
18 | rgb *= s;
19 | return rgb;
20 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/MidtoneContrast.dctl:
--------------------------------------------------------------------------------
1 | /* Midtone Contrast
2 | v0.0.1
3 | A more sophisticated contrast operator with linear toe and shoulder sections.
4 | https://www.desmos.com/calculator/mqvhho1mf9
5 |
6 | Written by Jed Smith
7 | https://github.com/jedypod/open-display-transform
8 |
9 | License: GPL v3
10 | */
11 |
12 | DEFINE_UI_PARAMS(con, contrast, DCTLUI_SLIDER_FLOAT, 0.0, -3.0, 2.0, 0.0)
13 | DEFINE_UI_PARAMS(pv, pivot, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
14 | DEFINE_UI_PARAMS(sh, shoulder, DCTLUI_SLIDER_FLOAT, 0.0, 0.0, 4.0, 0.0)
15 | DEFINE_UI_PARAMS(toe, toe, DCTLUI_SLIDER_FLOAT, 0.2, 0.0, 1.0, 0.0)
16 | DEFINE_UI_PARAMS(rp, preserve ratios, DCTLUI_SLIDER_FLOAT, 0.0, 0.0, 1.0, 0.0)
17 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
18 |
19 |
20 | __DEVICE__ float spowf(float x, float p) { return x <= 0.0f ? x : _powf(x, p); }
21 | __DEVICE__ float sdivf(float a, float b) { return _fabs(b) < 1e-6f ? 0.0f : a/b; }
22 |
23 | __DEVICE__ float contrast(float x, float s0, float s1, float p, float o, float m0, float m1, float tlx, float tly, float tux, float tuy, int inv) {
24 | if (inv == 0) {
25 | return s1*(x3.0.CO;2-R
7 |
8 | Clarification of differences between variable achromatic color and variable chromatic color methods in the Helmholtz–Kohlrausch effect
9 | Yoshinobu Nayatani, Hideki Sakai
10 | https://doi.org/10.1002/col.20194
11 |
12 | Prediction of the Helmholtz-Kohlrausch effect using the CIELUV formula
13 | Yoshinobu Nayatani, Motohiro Nakajima
14 | https://doi.org/10.1002/(SICI)1520-6378(199608)21:4<252::AID-COL1>3.0.CO;2-P
15 | */
16 |
17 | DEFINE_UI_PARAMS(in_gamut, input gamut, DCTLUI_COMBO_BOX, 1, {ap0, ap1, p3d65, rec2020, rec709, awg, rwg, sgamut3, blackmagicwg, egamut, davinciwg}, {ACES, ACEScg, P3D65, Rec.2020, Rec.709, Alexa Wide Gamut, Red Wide Gamut RGB, Sony SGamut3, Blackmagic Wide Gamut, Filmlight E - Gamut, DaVinci Wide Gamut})
18 | DEFINE_UI_PARAMS(wp, whitepoint, DCTLUI_COMBO_BOX, 3, {D50, D55, D60, D65}, {D50, D55, D60, D65})
19 | DEFINE_UI_PARAMS(La, L adapt, DCTLUI_SLIDER_FLOAT, 63.61, 0, 200, 1)
20 | DEFINE_UI_PARAMS(meth, method, DCTLUI_COMBO_BOX, 1, {VAC, VCC}, {VAC, VCC})
21 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
22 |
23 | __CONSTANT__ float pi = 3.14159265358979323846f;
24 |
25 | // Custom 3x3 matrix struct float3x3
26 | typedef struct {
27 | float3 x, y, z;
28 | } float3x3;
29 |
30 | // Helper function to create a float3x3
31 | __DEVICE__ float3x3 make_float3x3(float3 a, float3 b, float3 c) {
32 | float3x3 d;
33 | d.x = a, d.y = b, d.z = c;
34 | return d;
35 | }
36 |
37 | // Multiply float3 vector a and 3x3 matrix m
38 | __DEVICE__ float3 mult_f3_f33(float3 a, float3x3 m) {
39 | return make_float3(
40 | m.x.x * a.x + m.x.y * a.y + m.x.z * a.z,
41 | m.y.x * a.x + m.y.y * a.y + m.y.z * a.z,
42 | m.z.x * a.x + m.z.y * a.y + m.z.z * a.z);
43 | }
44 |
45 | #define identity_mtx make_float3x3(make_float3(1.0f, 0.0f, 0.0f), make_float3(0.0f, 1.0f, 0.0f), make_float3(0.0f, 0.0f, 1.0f))
46 | #define matrix_ap0_to_xyz make_float3x3(make_float3(0.950362384319f, 0.000000000000f, 0.000093463248f), make_float3(0.343966454268f, 0.728166162968f, -0.072132542729f), make_float3(0.000000000000f, 0.000000000000, 1.089057803154f))
47 | #define matrix_ap1_to_xyz make_float3x3(make_float3(0.660931229591f, 0.133696138859f, 0.155828580260f), make_float3(0.272228747606f, 0.674081742764f, 0.053689509630f), make_float3(-0.006018006243f, 0.004383686464, 1.090692043304f))
48 | #define matrix_p3d65_to_xyz make_float3x3(make_float3(0.486571133137f, 0.265667706728f, 0.198217317462f), make_float3(0.228974640369f, 0.691738605499f, 0.079286918044f), make_float3(-0.000000000000f, 0.045113388449, 1.043944478035f))
49 | #define matrix_p3d60_to_xyz make_float3x3(make_float3(0.504949748516f, 0.264681518078f, 0.183015048504f), make_float3(0.237623393536f, 0.689170777798f, 0.073206014931f), make_float3(-0.000000000000f, 0.044945921749f, 0.963879227638f))
50 | #define matrix_p3dci_to_xyz make_float3x3(make_float3(0.445170015097f, 0.277134418488f, 0.172282665968f), make_float3(0.209491759539f, 0.721595287323f, 0.068913064897f), make_float3(-0.000000000000f, 0.047060567886f, 0.907355427742f))
51 | #define matrix_rec2020_to_xyz make_float3x3(make_float3(0.636958122253f, 0.144616916776f, 0.168880969286f), make_float3(0.262700229883f, 0.677998125553f, 0.059301715344f), make_float3(0.000000000000f, 0.028072696179, 1.060985088348f))
52 | #define matrix_rec709_to_xyz make_float3x3(make_float3(0.412390917540f, 0.357584357262f, 0.180480793118f), make_float3(0.212639078498f, 0.715168714523f, 0.072192311287f), make_float3(0.019330825657f, 0.119194783270f, 0.950532138348f))
53 | #define matrix_arriwg_to_xyz make_float3x3(make_float3(0.638007640839f, 0.214703813195f, 0.097744457424f), make_float3(0.291953772306f, 0.823840856552f, -0.115794822574f), make_float3(0.002798279049f, -0.067034222186, 1.153293848038f))
54 | #define matrix_redwg_to_xyz make_float3x3(make_float3(0.735275208950f, 0.068609409034f, 0.146571278572f), make_float3(0.286694079638f, 0.842979073524f, -0.129673242569f), make_float3(-0.079680845141f, -0.347343206406, 1.516081929207f))
55 | #define matrix_sonysgamut3 make_float3x3(make_float3(0.599083900452f, 0.248925492167f, 0.102446496487f), make_float3(0.215075820684f, 0.885068416595f, -0.100144319236f), make_float3(-0.032065849751f, -0.027658388019, 1.148782014847f))
56 | #define matrix_blackmagicwg_to_xyz make_float3x3(make_float3(0.606538414955f, 0.220412746072f, 0.123504832387f), make_float3(0.267992943525f, 0.832748472691f, -0.100741356611f), make_float3(-0.029442556202f, -0.086612440646, 1.205112814903f))
57 | #define matrix_egamut_to_xyz make_float3x3(make_float3(0.705396831036f, 0.164041340351f, 0.081017754972f), make_float3(0.280130714178f, 0.820206701756f, -0.100337378681f), make_float3(-0.103781513870f, -0.072907261550, 1.265746593475f))
58 | #define matrix_davinciwg_to_xyz make_float3x3(make_float3(0.700622320175f, 0.148774802685f, 0.101058728993f), make_float3(0.274118483067f, 0.873631775379f, -0.147750422359f), make_float3(-0.098962903023f, -0.137895315886, 1.325916051865f))
59 |
60 | __DEVICE__ float _radians(float d) {return d * (pi / 180.0f);}
61 | __DEVICE__ float _degrees(float r) {return r * (180.0f / pi);}
62 | __DEVICE__ float3 maxf3(float3 a, float b) { return make_float3(_fmaxf(a.x, b), _fmaxf(a.y, b), _fmaxf(a.z, b)); }
63 |
64 |
65 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
66 | {
67 |
68 | float3 rgb = make_float3(p_R, p_G, p_B);
69 |
70 | // Input gamut conversion to D65 aligned XYZ (CAT: xyz scaling)
71 | float3x3 in_to_xyz;
72 | if (in_gamut == ap0) in_to_xyz = matrix_ap0_to_xyz;
73 | else if (in_gamut == ap1) in_to_xyz = matrix_ap1_to_xyz;
74 | else if (in_gamut == p3d65) in_to_xyz = matrix_p3d65_to_xyz;
75 | else if (in_gamut == rec2020) in_to_xyz = matrix_rec2020_to_xyz;
76 | else if (in_gamut == rec709) in_to_xyz = matrix_rec709_to_xyz;
77 | else if (in_gamut == awg) in_to_xyz = matrix_arriwg_to_xyz;
78 | else if (in_gamut == rwg) in_to_xyz = matrix_redwg_to_xyz;
79 | else if (in_gamut == sgamut3) in_to_xyz = matrix_sonysgamut3;
80 | else if (in_gamut == blackmagicwg) in_to_xyz = matrix_blackmagicwg_to_xyz;
81 | else if (in_gamut == egamut) in_to_xyz = matrix_egamut_to_xyz;
82 | else if (in_gamut == davinciwg) in_to_xyz = matrix_davinciwg_to_xyz;
83 |
84 | // Reference white illuminant
85 | float2 w_xy;
86 | if (wp == D50) w_xy = make_float2(0.3457f, 0.3585f);
87 | else if (wp == D55) w_xy = make_float2(0.33243f, 0.34744f);
88 | else if (wp == D60) w_xy = make_float2(0.321626f, 0.337737f);
89 | else if (wp == D65) w_xy = make_float2(0.3127f, 0.329f);
90 |
91 | const float w_uv_d = (-2.0f * w_xy.x + 12.0f * w_xy.y + 3.0f);
92 | const float2 w_uv = make_float2(4.0f * w_xy.x / w_uv_d, 9.0f * w_xy.y / w_uv_d);
93 |
94 | // Convert RGB to XYZ
95 | float3 xyz = mult_f3_f33(rgb, in_to_xyz);
96 |
97 | xyz = maxf3(xyz, 0.0f);
98 |
99 | // Convert XYZ to L*u'v'
100 | float d = xyz.x + 15.0f * xyz.y + 3.0f * xyz.z;
101 | const float _e = 216.0f / 24389.0f;
102 | const float _k = 24389.0f / 27.0f;
103 | float3 Luv = make_float3((xyz.y > _e ? 116.0f * _powf(xyz.y, 1.0f / 3.0f) - 16.0f : xyz.y * _k) / 100.0f,
104 | d == 0.0f ? 0.0f : 4.0f * xyz.x / d,
105 | d == 0.0f ? 0.0f : 9.0f * xyz.y / d);
106 |
107 | // Calculate Nayatani 1997 Helmholtz-Kohlrausch compensation factor
108 | float m = meth == VAC ? -0.866f : -0.134f;
109 | const float K_Br = 0.2717f * (6.469f + 6.362f * _powf(La, 0.4495f)) / (6.469f + _powf(La, 0.4495f));
110 |
111 | // Hue angle in radians
112 | float h = _atan2f(Luv.z - w_uv.y, Luv.y - w_uv.x);
113 | h = h < 0.0f ? h + _radians(360.0f) : h;
114 |
115 | float q = -0.01585f - 0.03017f * _cosf(h) - 0.04556f * _cosf(2.0f * h) - 0.02667f * _cosf(3.0f * h) - 0.00295f * _cosf(4.0f * h) + 0.14592f * _sinf(h) + 0.05084f * _sinf(2.0f * h) - 0.01900f * _sinf(3.0f * h) - 0.00764f * _sinf(4.0f * h);
116 | float S_uv = 13.0f * _hypotf(Luv.y - w_uv.x, Luv.z - w_uv.y);
117 |
118 | float s = (1.0f + (m * q + 0.0872f * K_Br) * S_uv);
119 | s = s == 0.0f ? 1.0f : 1.0f / s;
120 |
121 | if (invert == 1)
122 | rgb /= s;
123 | else
124 | rgb *= s;
125 |
126 | return rgb;
127 |
128 | };
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/Purity.dctl:
--------------------------------------------------------------------------------
1 | /* Purity - v0.0.1
2 | -------------------------
3 | Simpler weighted-sum based version of n6Purity. Probably more robust through variations in hue.
4 |
5 | ---
6 | Written by Jed Smith
7 | github.com/jedypod/open-display-transform
8 | */
9 |
10 | DEFINE_UI_PARAMS(purity, purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
11 | DEFINE_UI_PARAMS(strength, strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
12 | DEFINE_UI_PARAMS(rw, red weight, DCTLUI_SLIDER_FLOAT, 0.25, 0.05, 1, 0)
13 | DEFINE_UI_PARAMS(bw, blue weight, DCTLUI_SLIDER_FLOAT, 0.1, 0.05, 1, 0)
14 |
15 |
16 | // Safe division of float a by float b
17 | __DEVICE__ float sdivf(float a, float b) { return _fabs(b) < 1e-3f ? 0.0f : a/b; }
18 |
19 | // Safe division of float3 a by float b
20 | __DEVICE__ float3 sdivf3f(float3 a, float b) { return make_float3(sdivf(a.x, b), sdivf(a.y, b), sdivf(a.z, b)); }
21 |
22 | // Safe power function raising float a to power float b
23 | __DEVICE__ float spowf(float a, float b) { return a <= 0.0f ? a : _powf(a, b); }
24 |
25 | // https://www.desmos.com/calculator/bdbstdsvvv
26 | __DEVICE__ float pivoted_power_cubic(float x, float m, float p) {
27 | m = 1.0f - _fabs(m);
28 | float a0 = p*(m - 1.0f);
29 | float b0 = (1.0f - m)*(p + 1.0f);
30 | return x <= 0.0f ? m*x : x > 1.0f ? x : x*(_powf(x, p)*(a0*x + b0) + m);
31 | }
32 |
33 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B) {
34 | float3 rgb = make_float3(p_R, p_G, p_B);
35 |
36 | float mx = _fmaxf(rgb.x, _fmaxf(rgb.y, rgb.z));
37 | float3 rats = sdivf3f(rgb, mx); // rgb ratios
38 | float3 rats_c = 1.0f - rats; // complement of rgb ratios
39 |
40 | float gw = 1.0f - (rw + bw); // green weight sums weights to 1
41 |
42 | float w = rats_c.x*rw + rats_c.y*gw + rats_c.z*bw; // "luminance" weights complement
43 | float c = _fmaxf(rats_c.x, _fmaxf(rats_c.y, rats_c.z)); // chroma
44 |
45 | float L = 1.0f - w; // "luminance" weights inside normalized rgb ratios
46 | w = sdivf(w, c); // chroma-normalized weights
47 |
48 | float f0 = sdivf(pivoted_power_cubic(c, purity, strength), c);
49 | float f1 = sdivf(1.0f - pivoted_power_cubic(1.0f - c, purity, strength), c);
50 |
51 | // Lerp factor for nonlinear "purity"/saturation adjustment.
52 | // decrease uses luminance weights (yellow highest, blue lowest)
53 | // increase uses chrominance weights (complement of luminance: yellow lowest, blue highest)
54 | float f = purity > 0.0f ? (w*f1 + (1.0f - w)) : ((1.0f - w)*f0 + w);
55 |
56 | // negatives could cause nan/inf in shadow grain.
57 | f = _fmaxf(0.0f, f);
58 |
59 | rats = L*(1.0f - f) + rats*f;
60 |
61 | rgb = rats * mx;
62 |
63 | return rgb;
64 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/Saturation.dctl:
--------------------------------------------------------------------------------
1 | DEFINE_UI_PARAMS(sag, global sat, DCTLUI_SLIDER_FLOAT, 1, 0, 2, 0)
2 | DEFINE_UI_PARAMS(sah, hue sat, DCTLUI_SLIDER_FLOAT, 1, 0, 2, 0)
3 | DEFINE_UI_PARAMS(ho, hue angle, DCTLUI_SLIDER_FLOAT, 1, 0, 6, 0)
4 | DEFINE_UI_PARAMS(hw, hue width, DCTLUI_SLIDER_FLOAT, 1, 0.1, 1.5, 0)
5 | DEFINE_UI_PARAMS(wr, weight red, DCTLUI_SLIDER_FLOAT, 0.23, 0, 1, 0)
6 | DEFINE_UI_PARAMS(wb, weight blue, DCTLUI_SLIDER_FLOAT, 0.08, 0, 1, 0)
7 | DEFINE_UI_PARAMS(lg, in log, DCTLUI_CHECK_BOX, 1)
8 | DEFINE_UI_PARAMS(ze, zone extract, DCTLUI_CHECK_BOX, 0)
9 | DEFINE_UI_PARAMS(zp, zone range, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
10 | DEFINE_UI_PARAMS(zone, zone, DCTLUI_COMBO_BOX, 1, {low, high}, {low, high})
11 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
12 | #include "libLMT.h"
13 |
14 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
15 | {
16 | float3 rgb = make_float3(p_R, p_G, p_B);
17 | rgb = linearize(rgb, tf, 0);
18 |
19 | int zr = zone == high ? 0 : 1;
20 |
21 | rgb = saturation(rgb, sag, sah, ho, hw, wr, wb, lg, ze, zp, zr);
22 | rgb = linearize(rgb, tf, 1);
23 | return rgb;
24 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/ShadowContrast.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(ex, exposure, DCTLUI_SLIDER_FLOAT, 0.0, -6.0, 0.0, 0.0)
5 | DEFINE_UI_PARAMS(str, strength, DCTLUI_SLIDER_FLOAT, 0.5, 0.0, 1.0, 0.0)
6 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
7 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
8 |
9 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
10 | {
11 | float3 rgb = make_float3(p_R, p_G, p_B);
12 | rgb = linearize(rgb, tf, 0);
13 | rgb = shd_con(rgb, ex, str, invert);
14 | rgb = linearize(rgb, tf, 1);
15 | return rgb;
16 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/XLog.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | /* XLog
3 | v0.0.1
4 | A flexible parameterized log function. This one has been floating around in my various tools for a while,
5 | but I figured it would be useful to have as a standalone. This is the variation that includes
6 | a linear extension at the specified slope value, instead of at a specific x coordinate.
7 |
8 | A couple of preset parameter values to start you off:
9 | XLog: Classic Cineon style log space for grading, similar to Filmlight's T-Log.
10 | w0 128 w1 1 o 7.5 k 0.06 x0 0 y0 0.075
11 |
12 | XLogHalf: Cineon style log space with less dynamic range up to 16. suitable for log grading in half float maybe?
13 | w0 16 w1 1 o 6.7 k 0.05 x0 0 y0 0.092
14 |
15 | XLogC: Camera encoding style log curve with an extended linear section in in the shadows, similar to Arri LogC3.
16 | w0 64 w1 1 o 7 k 0.18 x0 0.01 y0 0.15
17 |
18 |
19 | https://www.desmos.com/calculator/9pgjgo1gq4
20 |
21 | Google Colab Notebook with mathematical derivation and extra variations:
22 | https://colab.research.google.com/drive/1NwjaD0NzNMzQeNQqZECj33PdcYGkeBM4
23 |
24 |
25 | Written by Jed Smith
26 | https://github.com/jedypod/open-display-transform
27 |
28 | License: GPL v3
29 | */
30 |
31 | DEFINE_UI_PARAMS(w0, high x intersect, DCTLUI_SLIDER_FLOAT, 16, 10, 256, 0.0)
32 | DEFINE_UI_PARAMS(o, slope, DCTLUI_SLIDER_FLOAT, 6.7, 0, 12, 0.0)
33 | DEFINE_UI_PARAMS(x0, low x intersect, DCTLUI_SLIDER_FLOAT, 0, 0, 0.5, 0.0)
34 | DEFINE_UI_PARAMS(y0, low y intersect, DCTLUI_SLIDER_FLOAT, 0.092, 0, 0.5, 0.0)
35 | DEFINE_UI_PARAMS(k, lin ext slope, DCTLUI_SLIDER_FLOAT, 0.05, 0, 0.2, 0.0)
36 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
37 |
38 |
39 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
40 | {
41 |
42 | /* Pre-Calculations */
43 | // high y intersect is always 1.0
44 | const float w1 = 1.0f;
45 | // x offset: the y asymptote of the log curve
46 | const float o0 = -_powf(2.0f,-o);
47 | // s0: scale factor to satisfy intersection constraint at (x0, y0)
48 | const float s0 = (w1-y0)/_logf((w0-o0)/(x0-o0));
49 | // o1: y offset to satisfy intersection constraint at (w0, w1)
50 | const float o1 = w1-s0*_logf(w0-o0);
51 | // x1: x coordinate of linear extension intercept (controlled by user-specified slope k)
52 | const float x1 = s0*log(k*s0*_expf(o1/s0));
53 | // y1: is y coordinate of linear extension intercept
54 | const float y1 = _expf((x1-o1)/s0)+o0;
55 | // y (x=0) intercept of linear equation
56 | const float y2 = y1-k*x1;
57 |
58 | /* Shader Code */
59 | float3 rgb = make_float3(p_R, p_G, p_B);
60 |
61 | if (invert) {
62 | rgb.x = rgb.x < x1 ? k*rgb.x+y2 : _expf((rgb.x - o1)/s0) + o0;
63 | rgb.y = rgb.y < x1 ? k*rgb.y+y2 : _expf((rgb.y - o1)/s0) + o0;
64 | rgb.z = rgb.z < x1 ? k*rgb.z+y2 : _expf((rgb.z - o1)/s0) + o0;
65 | } else {
66 | rgb.x = rgb.x < y1 ? (rgb.x - y2)/k : s0*_logf(rgb.x - o0) + o1;
67 | rgb.y = rgb.y < y1 ? (rgb.y - y2)/k : s0*_logf(rgb.y - o0) + o1;
68 | rgb.z = rgb.z < y1 ? (rgb.z - y2)/k : s0*_logf(rgb.z - o0) + o1;
69 | }
70 |
71 | return rgb;
72 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/ZoneExposureHigh.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(ex, exposure, DCTLUI_SLIDER_FLOAT, 0.0, -5.0, 5.0, 0.0)
5 | DEFINE_UI_PARAMS(pv, pivot, DCTLUI_SLIDER_FLOAT, -1.0, -5.0, 5.0, 0.0)
6 | DEFINE_UI_PARAMS(fa, falloff, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
7 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
8 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
9 |
10 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
11 | {
12 | float3 rgb = make_float3(p_R, p_G, p_B);
13 | rgb = linearize(rgb, tf, 0);
14 | rgb = ex_high(rgb, ex, pv, fa, invert);
15 | rgb = linearize(rgb, tf, 1);
16 | return rgb;
17 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/ZoneExposureLow.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(ex, exposure, DCTLUI_SLIDER_FLOAT, 0.0, -5.0, 5.0, 0.0)
5 | DEFINE_UI_PARAMS(pv, pivot, DCTLUI_SLIDER_FLOAT, -1.0, -5.0, 5.0, 0.0)
6 | DEFINE_UI_PARAMS(fa, falloff, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
7 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
8 |
9 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
10 | {
11 | float3 rgb = make_float3(p_R, p_G, p_B);
12 | rgb = linearize(rgb, tf, 0);
13 | rgb = ex_low(rgb, ex, pv, fa);
14 | rgb = linearize(rgb, tf, 1);
15 | return rgb;
16 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/ZoneGrade.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(ex, exposure, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
5 | DEFINE_UI_PARAMS(c, contrast, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
6 | DEFINE_UI_PARAMS(pv, pivot, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
7 | DEFINE_UI_PARAMS(off, offset, DCTLUI_SLIDER_FLOAT, 0.0, -0.02, 0.02, 0.0)
8 | DEFINE_UI_PARAMS(he, exposure - H, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
9 | DEFINE_UI_PARAMS(hp, pivot - H, DCTLUI_SLIDER_FLOAT, -1.0, -4.0, 4.0, 0.0)
10 | DEFINE_UI_PARAMS(hf, falloff - H, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
11 | DEFINE_UI_PARAMS(le, exposure - L, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
12 | DEFINE_UI_PARAMS(lp, pivot - L, DCTLUI_SLIDER_FLOAT, 1.0, -4.0, 4.0, 0.0)
13 | DEFINE_UI_PARAMS(lf, falloff - L, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
14 | DEFINE_UI_PARAMS(he2, exposure - H2, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
15 | DEFINE_UI_PARAMS(hp2, pivot - H2, DCTLUI_SLIDER_FLOAT, 1.0, -4.0, 4.0, 0.0)
16 | DEFINE_UI_PARAMS(hf2, falloff - H2, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
17 | DEFINE_UI_PARAMS(le2, exposure - L2, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
18 | DEFINE_UI_PARAMS(lp2, pivot - L2, DCTLUI_SLIDER_FLOAT, -1.0, -4.0, 4.0, 0.0)
19 | DEFINE_UI_PARAMS(lf2, falloff - L2, DCTLUI_SLIDER_FLOAT, 0.6, 0.0, 1.0, 0.0)
20 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
21 |
22 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
23 | {
24 | float3 rgb = make_float3(p_R, p_G, p_B);
25 | rgb = linearize(rgb, tf, 0);
26 | rgb = zone_grade(rgb, ex, c, pv, off, he, hp, hf, le, lp, lf, he2, hp2, hf2, le2, lp2, lf2);
27 | rgb = linearize(rgb, tf, 1);
28 | return rgb;
29 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/ZoneSaturation.dctl:
--------------------------------------------------------------------------------
1 | /* ZoneSaturation
2 | A zoned saturation control with per-hue angle controls.
3 | The zones are defined by a hyperbolic extraction of input
4 |
5 | Input should be scene-linear.
6 |
7 | ---------------------------------------------------
8 | v0.0.2
9 | Written by Jed Smith
10 | github.com/jedypod/open-display-transform
11 | */
12 |
13 | DEFINE_UI_PARAMS(in_gamut, input gamut, DCTLUI_COMBO_BOX, 1, {ap0, ap1, p3d65, rec2020, rec709, awg, rwg, sgamut3, blackmagicwg, egamut, davinciwg}, {ACES, ACEScg, P3D65, Rec.2020, Rec.709, Alexa Wide Gamut, Red Wide Gamut RGB, Sony SGamut3, Blackmagic Wide Gamut, Filmlight E - Gamut, DaVinci Wide Gamut})
14 | DEFINE_UI_PARAMS(sat, sat, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
15 | DEFINE_UI_PARAMS(sal, sat low, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
16 | DEFINE_UI_PARAMS(zrl, range low, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
17 | DEFINE_UI_PARAMS(sah, sat high, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
18 | DEFINE_UI_PARAMS(zrh, range high, DCTLUI_SLIDER_FLOAT, 0.0, -4.0, 4.0, 0.0)
19 | DEFINE_UI_PARAMS(sy, sat yellow, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
20 | DEFINE_UI_PARAMS(sr, sat red, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
21 | DEFINE_UI_PARAMS(sm, sat magenta, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
22 | DEFINE_UI_PARAMS(sb, sat blue, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
23 | DEFINE_UI_PARAMS(sc, sat cyan, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
24 | DEFINE_UI_PARAMS(sg, sat green, DCTLUI_SLIDER_FLOAT, 1.0, 0.0, 2.0, 0.0)
25 | DEFINE_UI_PARAMS(pch, perceptual, DCTLUI_CHECK_BOX, 0)
26 | DEFINE_UI_PARAMS(zha, zone hue angle, DCTLUI_COMBO_BOX, 1, {none, low, high}, {none, low, high})
27 |
28 |
29 | #define catd65 make_float3(1.07046f, 0.916817f, 0.594251f)
30 | // Gamut conversion Matrices
31 | #define identity_mtx make_float3x3(make_float3(1.0f, 0.0f, 0.0f), make_float3(0.0f, 1.0f, 0.0f), make_float3(0.0f, 0.0f, 1.0f))
32 | #define matrix_ap0_to_xyz make_float3x3(make_float3(0.950362384319f, 0.000000000000f, 0.000093463248f), make_float3(0.343966454268f, 0.728166162968f, -0.072132542729f), make_float3(0.000000000000f, 0.000000000000, 1.089057803154f))
33 | #define matrix_ap1_to_xyz make_float3x3(make_float3(0.660931229591f, 0.133696138859f, 0.155828580260f), make_float3(0.272228747606f, 0.674081742764f, 0.053689509630f), make_float3(-0.006018006243f, 0.004383686464, 1.090692043304f))
34 | #define matrix_p3d65_to_xyz make_float3x3(make_float3(0.486571133137f, 0.265667706728f, 0.198217317462f), make_float3(0.228974640369f, 0.691738605499f, 0.079286918044f), make_float3(-0.000000000000f, 0.045113388449, 1.043944478035f))
35 | #define matrix_p3d60_to_xyz make_float3x3(make_float3(0.504949748516f, 0.264681518078f, 0.183015048504f), make_float3(0.237623393536f, 0.689170777798f, 0.073206014931f), make_float3(-0.000000000000f, 0.044945921749f, 0.963879227638f))
36 | #define matrix_p3dci_to_xyz make_float3x3(make_float3(0.445170015097f, 0.277134418488f, 0.172282665968f), make_float3(0.209491759539f, 0.721595287323f, 0.068913064897f), make_float3(-0.000000000000f, 0.047060567886f, 0.907355427742f))
37 | #define matrix_rec2020_to_xyz make_float3x3(make_float3(0.636958122253f, 0.144616916776f, 0.168880969286f), make_float3(0.262700229883f, 0.677998125553f, 0.059301715344f), make_float3(0.000000000000f, 0.028072696179, 1.060985088348f))
38 | #define matrix_rec709_to_xyz make_float3x3(make_float3(0.412390917540f, 0.357584357262f, 0.180480793118f), make_float3(0.212639078498f, 0.715168714523f, 0.072192311287f), make_float3(0.019330825657f, 0.119194783270f, 0.950532138348f))
39 | #define matrix_arriwg_to_xyz make_float3x3(make_float3(0.638007640839f, 0.214703813195f, 0.097744457424f), make_float3(0.291953772306f, 0.823840856552f, -0.115794822574f), make_float3(0.002798279049f, -0.067034222186, 1.153293848038f))
40 | #define matrix_redwg_to_xyz make_float3x3(make_float3(0.735275208950f, 0.068609409034f, 0.146571278572f), make_float3(0.286694079638f, 0.842979073524f, -0.129673242569f), make_float3(-0.079680845141f, -0.347343206406, 1.516081929207f))
41 | #define matrix_sonysgamut3 make_float3x3(make_float3(0.599083900452f, 0.248925492167f, 0.102446496487f), make_float3(0.215075820684f, 0.885068416595f, -0.100144319236f), make_float3(-0.032065849751f, -0.027658388019, 1.148782014847f))
42 | #define matrix_egamut_to_xyz make_float3x3(make_float3(0.705396831036f, 0.164041340351f, 0.081017754972f), make_float3(0.280130714178f, 0.820206701756f, -0.100337378681f), make_float3(-0.103781513870f, -0.072907261550, 1.265746593475f))
43 | #define matrix_davinciwg_to_xyz make_float3x3(make_float3(0.700622320175f, 0.148774802685f, 0.101058728993f), make_float3(0.274118483067f, 0.873631775379f, -0.147750422359f), make_float3(-0.098962903023f, -0.137895315886, 1.325916051865f))
44 | #define matrix_blackmagicwg_to_xyz make_float3x3(make_float3(0.606538414955f, 0.220412746072f, 0.123504832387f), make_float3(0.267992943525f, 0.832748472691f, -0.100741356611f), make_float3(-0.029442556202f, -0.086612440646, 1.205112814903f))
45 |
46 | /* Matrix for conversion from CIE 1931 XYZ tristumulus to CIE 2006 LMS or "Truelight LMS", described in:
47 | "Chromaticity Coordinates for Graphic Arts Based on CIE 2006 LMS with Even Spacing of Munsell Colours" by Richard Kirk
48 | https://doi.org/10.2352/issn.2169-2629.2019.27.38
49 | */
50 | #define matrix_xyz_to_truelightlms make_float3x3(make_float3(0.257085f, 0.859943f, -0.031061f), make_float3(-0.394427, 1.175800f, 0.106423f), make_float3(0.064856f, -0.07625f, 0.559067f))
51 |
52 | #define matrix_jzazbz_xyz_to_lms make_float3x3(make_float3(0.41479f, 0.579999f, 0.014648f), make_float3(-0.20151f, 1.12065f, 0.0531008f), make_float3(-0.0166008f, 0.2648f, 0.66848f))
53 | #define matrix_jzazbz_lms_p_to_izazbz make_float3x3(make_float3(0.5f, 0.5f, 0.0f), make_float3(3.524f, -4.06671f, 0.542708f), make_float3(0.199076f, 1.0968f, -1.29588f))
54 |
55 |
56 |
57 |
58 | // Custom 3x3 matrix struct float3x3
59 | typedef struct {
60 | float3 x, y, z;
61 | } float3x3;
62 |
63 | __DEVICE__ float extract(float e0, float e1, float x) {
64 | // Extract a range from e0 to e1 from f, clamping values above or below.
65 | return _clampf((x - e0) / (e1 - e0), 0.0f, 1.0f);
66 | }
67 |
68 | __DEVICE__ float extract_window(float e0, float e1, float e2, float e3, float x) {
69 | // Linear window function to extract a range from float x
70 | // https://www.desmos.com/calculator/uzsk5ta5v7
71 | return x < e1 ? extract(e0, e1, x) : extract(e3, e2, x);
72 | }
73 |
74 | __DEVICE__ float extract_hue_angle(float h, float o, float w) {
75 | // Given hue, offset, width, and chroma, extract hue angle
76 | float hc = extract_window(2.0f - w, 2.0f, 2.0f, 2.0f + w, _fmod(h + o, 6.0f));
77 | hc = hc * hc * (3.0f - 2.0f * hc); // smoothstep
78 | return hc;
79 | }
80 |
81 |
82 | __DEVICE__ float _sign(float x) {
83 | // Return the sign of float x
84 | if (x > 0.0f) return 1.0f;
85 | if (x < 0.0f) return -1.0f;
86 | return 0.0f;
87 | }
88 | __DEVICE__ float3 powf3(float3 a, float b) {
89 | // Raise each component of float3 a to power b
90 | return make_float3(_powf(a.x, b), _powf(a.y, b), _powf(a.z, b));
91 | }
92 |
93 | __DEVICE__ float3 spowf3(float3 a, float b) {
94 | // Compute "safe" power of float3 a, reflected over the origin
95 | return make_float3(
96 | _sign(a.x)*_powf(_fabs(a.x), b),
97 | _sign(a.y)*_powf(_fabs(a.y), b),
98 | _sign(a.z)*_powf(_fabs(a.z), b));
99 | }
100 |
101 | __DEVICE__ float3 cartesian_to_polar(float3 a) {
102 | return make_float3(a.x, _hypotf(a.y, a.z), _atan2f(a.z, a.y));
103 | }
104 |
105 | __DEVICE__ float3 polar_to_cartesian(float3 a) {
106 | return make_float3(a.x, a.y * _cosf(a.z), a.y * _sinf(a.z));
107 | }
108 |
109 |
110 | // Helper function to create a float3x3
111 | __DEVICE__ float3x3 make_float3x3(float3 a, float3 b, float3 c) {
112 | float3x3 d;
113 | d.x = a, d.y = b, d.z = c;
114 | return d;
115 | }
116 | // Multiply float3 vector a and 3x3 matrix m
117 | __DEVICE__ float3 mult_f3_f33(float3 a, float3x3 m) {
118 | return make_float3(
119 | m.x.x * a.x + m.x.y * a.y + m.x.z * a.z,
120 | m.y.x * a.x + m.y.y * a.y + m.y.z * a.z,
121 | m.z.x * a.x + m.z.y * a.y + m.z.z * a.z);
122 | }
123 | // Calculate inverse of 3x3 matrix: https://stackoverflow.com/questions/983999/simple-3x3-matrix-inverse-code-c
124 | __DEVICE__ float3x3 inv_f33(float3x3 m) {
125 | float d = m.x.x * (m.y.y * m.z.z - m.z.y * m.y.z) -
126 | m.x.y * (m.y.x * m.z.z - m.y.z * m.z.x) +
127 | m.x.z * (m.y.x * m.z.y - m.y.y * m.z.x);
128 | float id = 1.0f / d;
129 | float3x3 c = identity_mtx;
130 | c.x.x = id * (m.y.y * m.z.z - m.z.y * m.y.z);
131 | c.x.y = id * (m.x.z * m.z.y - m.x.y * m.z.z);
132 | c.x.z = id * (m.x.y * m.y.z - m.x.z * m.y.y);
133 | c.y.x = id * (m.y.z * m.z.x - m.y.x * m.z.z);
134 | c.y.y = id * (m.x.x * m.z.z - m.x.z * m.z.x);
135 | c.y.z = id * (m.y.x * m.x.z - m.x.x * m.y.z);
136 | c.z.x = id * (m.y.x * m.z.y - m.z.x * m.y.y);
137 | c.z.y = id * (m.z.x * m.x.y - m.x.x * m.z.y);
138 | c.z.z = id * (m.x.x * m.y.y - m.y.x * m.x.y);
139 | return c;
140 | }
141 |
142 | __DEVICE__ float hue(float3 rgb) {
143 | // Calculate and return hue in degrees between 0 and 6
144 | float mx = _fmaxf(rgb.x, _fmaxf(rgb.y, rgb.z));
145 | float mn = _fminf(rgb.x, _fminf(rgb.y, rgb.z));
146 | float ch = mx - mn;
147 | float h;
148 | if (ch == 0.0f) h = 0.0f;
149 | else if (mx == rgb.x) h = _fmod((rgb.y - rgb.z) / ch + 6.0f, 6.0f);
150 | else if (mx == rgb.y) h = (rgb.z - rgb.x) / ch + 2.0f;
151 | else if (mx == rgb.z) h = (rgb.x - rgb.y) / ch + 4.0f;
152 | return h;
153 | }
154 |
155 |
156 | __DEVICE__ float3 eotf_pq(float3 rgb, int inverse, int jz) {
157 | // Apply the ST-2084 PQ Forward or Inverse EOTF
158 | // Normalized such that input display linear light code value 1.0 equals 10,000 nits
159 | // ITU-R Rec BT.2100-2 https://www.itu.int/rec/R-REC-BT.2100
160 | // ITU-R Rep BT.2390-9 https://www.itu.int/pub/R-REP-BT.2390
161 |
162 | float Lp = 1.0f; // We normalize for hdr peak display luminance elsewhere.
163 | const float m1 = 2610.0f / 16384.0f;
164 | float m2 = 2523.0f / 32.0f;
165 | const float c1 = 107.0f / 128.0f;
166 | const float c2 = 2413.0f / 128.0f;
167 | const float c3 = 2392.0f / 128.0f;
168 |
169 | // Custom values for JzAzBz colorspace
170 | if (jz == 1) {
171 | m2 *= 1.7f;
172 | Lp = 10000.0f;
173 | }
174 |
175 | if (inverse == 1) {
176 | rgb /= Lp;
177 | rgb = spowf3(rgb, m1);
178 | // Prevent shitting of the bed when there are negatives, for JzAzBz conversion
179 | rgb.x = _sign(rgb.x) * _powf((c1 + c2 * _fabs(rgb.x)) / (1.0f + c3 * _fabs(rgb.x)), m2);
180 | rgb.y = _sign(rgb.y) * _powf((c1 + c2 * _fabs(rgb.y)) / (1.0f + c3 * _fabs(rgb.y)), m2);
181 | rgb.z = _sign(rgb.z) * _powf((c1 + c2 * _fabs(rgb.z)) / (1.0f + c3 * _fabs(rgb.z)), m2);
182 | } else {
183 | rgb = spowf3(rgb, 1.0f / m2);
184 | rgb.x = _sign(rgb.x) * _powf((_fabs(rgb.x) - c1) / (c2 - c3 * _fabs(rgb.x)), 1.0f / m1) * Lp;
185 | rgb.y = _sign(rgb.y) * _powf((_fabs(rgb.y) - c1) / (c2 - c3 * _fabs(rgb.y)), 1.0f / m1) * Lp;
186 | rgb.z = _sign(rgb.z) * _powf((_fabs(rgb.z) - c1) / (c2 - c3 * _fabs(rgb.z)), 1.0f / m1) * Lp;
187 | }
188 | return rgb;
189 | }
190 | __DEVICE__ float3 xyz_to_jzlms(float3 xyz) {
191 | float3 lms;
192 | lms = make_float3(1.15f * xyz.x - (1.15f - 1.0f) * xyz.z,
193 | 0.66f * xyz.y - (0.66f - 1.0f) * xyz.x,
194 | xyz.z);
195 | lms = mult_f3_f33(lms, matrix_jzazbz_xyz_to_lms);
196 | return lms;
197 | }
198 |
199 | __DEVICE__ float3 jzlms_to_xyz(float3 lms) {
200 | float3 xyz;
201 | xyz = mult_f3_f33(lms, inv_f33(matrix_jzazbz_xyz_to_lms));
202 | xyz = make_float3(
203 | (xyz.x + (1.15f - 1.0f) * xyz.z) / 1.15f,
204 | (xyz.y + (0.66f - 1.0f) * ((xyz.x + (1.15f - 1.0f) * xyz.z) / 1.15f)) / 0.66f,
205 | xyz.z);
206 | return xyz;
207 | }
208 |
209 | __DEVICE__ float3 xyz_to_jzazbz(float3 xyz, int cyl) {
210 | // Convert input XYZ D65 aligned tristimulus values into JzAzBz perceptual colorspace,
211 | // if cyl==1: output cylindrical JCh : J = luma, C = chroma, h = hue in radians
212 | const float d = -0.56f;
213 | const float d_0 = 1.6295499532821565e-11f;
214 | float3 lms;
215 | lms = xyz_to_jzlms(xyz);
216 | lms = eotf_pq(lms, 1, 1);
217 | lms = mult_f3_f33(lms, matrix_jzazbz_lms_p_to_izazbz);
218 | lms.x = lms.x * (1.0f + d) / (1.0f + d * lms.x) - d_0;
219 |
220 | // Convert to cylindrical
221 | if (cyl == 1) lms = cartesian_to_polar(lms);
222 |
223 | return lms;
224 | }
225 |
226 |
227 | __DEVICE__ float3 jzazbz_to_xyz(float3 jz, int cyl) {
228 | const float d = -0.56f;
229 | const float d_0 = 1.6295499532821565e-11f;
230 | // Convert to cartesian
231 | if (cyl == 1) jz = polar_to_cartesian(jz);
232 |
233 | jz.x = (jz.x + d_0) / (1.0f + d - d * (jz.x + d_0));
234 | jz = mult_f3_f33(jz, inv_f33(matrix_jzazbz_lms_p_to_izazbz));
235 | jz = eotf_pq(jz, 0, 1);
236 | jz = jzlms_to_xyz(jz);
237 | return jz;
238 | }
239 |
240 |
241 |
242 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
243 | {
244 | float3 rgb, lms, xyz;
245 | const float3x3 xyz_to_lms = matrix_xyz_to_truelightlms;
246 | const float3x3 lms_to_xyz = inv_f33(matrix_xyz_to_truelightlms);
247 |
248 | // Input gamut conversion to D65 aligned XYZ (CAT: xyz scaling)
249 | float3x3 in_to_xyz;
250 | if (in_gamut == ap0) in_to_xyz = matrix_ap0_to_xyz;
251 | else if (in_gamut == ap1) in_to_xyz = matrix_ap1_to_xyz;
252 | else if (in_gamut == p3d65) in_to_xyz = matrix_p3d65_to_xyz;
253 | else if (in_gamut == rec2020) in_to_xyz = matrix_rec2020_to_xyz;
254 | else if (in_gamut == rec709) in_to_xyz = matrix_rec709_to_xyz;
255 | else if (in_gamut == awg) in_to_xyz = matrix_arriwg_to_xyz;
256 | else if (in_gamut == rwg) in_to_xyz = matrix_redwg_to_xyz;
257 | else if (in_gamut == sgamut3) in_to_xyz = matrix_sonysgamut3;
258 | else if (in_gamut == blackmagicwg) in_to_xyz = matrix_blackmagicwg_to_xyz;
259 | else if (in_gamut == egamut) in_to_xyz = matrix_egamut_to_xyz;
260 | else if (in_gamut == davinciwg) in_to_xyz = matrix_davinciwg_to_xyz;
261 | const float3x3 xyz_to_in = inv_f33(in_to_xyz);
262 |
263 |
264 | rgb = make_float3(p_R, p_G, p_B);
265 |
266 | xyz = mult_f3_f33(rgb, in_to_xyz);
267 | lms = mult_f3_f33(xyz, xyz_to_lms);
268 | lms /= catd65;
269 |
270 | float n = (lms.x + lms.y + lms.z) / 3.0f;
271 | float fh = _powf(n / (n + 1.0f), 1.0f / _powf(2.0f, zrh));
272 | float fl = _powf(1.0f / (n + 1.0f), 1.0f / _powf(2.0f, zrl));
273 |
274 | float fha; // factor for hue angle
275 | if (zha == none) fha = 1.0f;
276 | else if (zha == low) fha = fl;
277 | else if (zha == high) fha = fh;
278 |
279 | // Global saturation
280 | lms = n * (1.0f - sat) + lms * sat;
281 |
282 | // Zoned saturation low
283 | lms = lms * (1.0f - fh) + (n * (1.0f - sah) + lms * sah) * fh;
284 |
285 | // Zoned saturation high
286 | lms = lms * (1.0f - fl) + (n * (1.0f - sal) + lms * sal) * fl;
287 |
288 | // Hue Angle Controls
289 | float h = hue(rgb);
290 | // hue extraction for primaries (RGB)
291 | float3 hep = make_float3(
292 | extract_hue_angle(h, 2.0f, 1.0f),
293 | extract_hue_angle(h, 6.0f, 1.0f),
294 | extract_hue_angle(h, 4.0f, 1.0f));
295 | // hue extraction for secondaries (CMY)
296 | float3 hes = make_float3(
297 | extract_hue_angle(h, 5.0f, 1.0f),
298 | extract_hue_angle(h, 3.0f, 1.0f),
299 | extract_hue_angle(h, 1.0f, 1.0f));
300 | // Per hue angle saturation, mixed by factor hue angle fha
301 | lms.x = lms.x*(1.0f-fha)+((n*(1.0f-sr)+lms.x*sr)*hep.x+(n*(1.0f-sg)+lms.x*sg)*hep.y+(n*(1.0f-sb)+lms.x*sb)*hep.z+lms.x*(1.0f-(hep.x+hep.y+hep.z)))*fha;
302 | lms.y = lms.y*(1.0f-fha)+((n*(1.0f-sr)+lms.y*sr)*hep.x+(n*(1.0f-sg)+lms.y*sg)*hep.y+(n*(1.0f-sb)+lms.y*sb)*hep.z+lms.y*(1.0f-(hep.x+hep.y+hep.z)))*fha;
303 | lms.z = lms.z*(1.0f-fha)+((n*(1.0f-sr)+lms.z*sr)*hep.x+(n*(1.0f-sg)+lms.z*sg)*hep.y+(n*(1.0f-sb)+lms.z*sb)*hep.z+lms.z*(1.0f-(hep.x+hep.y+hep.z)))*fha;
304 |
305 | lms.x = lms.x*(1.0f-fha)+((n*(1.0f-sc)+lms.x*sc)*hes.x+(n*(1.0f-sm)+lms.x*sm)*hes.y+(n*(1.0f-sy)+lms.x*sy)*hes.z+lms.x*(1.0f-(hes.x+hes.y+hes.z)))*fha;
306 | lms.y = lms.y*(1.0f-fha)+((n*(1.0f-sc)+lms.y*sc)*hes.x+(n*(1.0f-sm)+lms.y*sm)*hes.y+(n*(1.0f-sy)+lms.y*sy)*hes.z+lms.y*(1.0f-(hes.x+hes.y+hes.z)))*fha;
307 | lms.z = lms.z*(1.0f-fha)+((n*(1.0f-sc)+lms.z*sc)*hes.x+(n*(1.0f-sm)+lms.z*sm)*hes.y+(n*(1.0f-sy)+lms.z*sy)*hes.z+lms.z*(1.0f-(hes.x+hes.y+hes.z)))*fha;
308 |
309 | lms *= catd65;
310 | float3 out_xyz = mult_f3_f33(lms, lms_to_xyz);
311 |
312 | if (pch == 1) {
313 | float3 jz = xyz_to_jzazbz(out_xyz, 1);
314 | float3 jz_nch = xyz_to_jzazbz(xyz, 1);
315 | jz.z = jz_nch.z;
316 | out_xyz = jzazbz_to_xyz(jz, 1);
317 | }
318 |
319 | rgb = mult_f3_f33(out_xyz, xyz_to_in);
320 |
321 | return rgb;
322 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/n6ChromaValue.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(my, yellow, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
5 | DEFINE_UI_PARAMS(mr, red, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
6 | DEFINE_UI_PARAMS(mm, magenta, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
7 | DEFINE_UI_PARAMS(mb, blue, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
8 | DEFINE_UI_PARAMS(mc, cyan, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
9 | DEFINE_UI_PARAMS(mg, green, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
10 | DEFINE_UI_PARAMS(hs_rgb, hue strength rgb, DCTLUI_SLIDER_FLOAT, 2, 1, 4, 0)
11 | DEFINE_UI_PARAMS(hs_cmy, hue strength cmy, DCTLUI_SLIDER_FLOAT, 2, 1, 4, 0)
12 | DEFINE_UI_PARAMS(chs, chroma strength, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
13 | DEFINE_UI_PARAMS(chl, chroma limit, DCTLUI_SLIDER_FLOAT, 0.0, 0, 1, 0)
14 | DEFINE_UI_PARAMS(ze, zone extract, DCTLUI_CHECK_BOX, 0)
15 | DEFINE_UI_PARAMS(zp, zone range, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
16 | DEFINE_UI_PARAMS(zone, zone, DCTLUI_COMBO_BOX, 1, {low, high}, {low, high})
17 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
18 |
19 |
20 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
21 | {
22 | float3 rgb = make_float3(p_R, p_G, p_B);
23 | rgb = linearize(rgb, tf, 0);
24 |
25 | int zr = 0;
26 | if (zone == high) zr = 1;
27 |
28 | rgb = n6_chroma_value(rgb, my, mr, mm, mb, mc, mg, hs_rgb, hs_cmy, chs, chl, ze, zp, zr);
29 | rgb = linearize(rgb, tf, 1);
30 | return rgb;
31 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/n6CrossTalk.dctl:
--------------------------------------------------------------------------------
1 | /* n6CrossTalk - v0.0.1
2 | -------------------------
3 | Another tool for distorting hues in an intentional way.
4 | Similar to n6HueShift, but with more flexibility and control.
5 | Uses different methods for distorting hue for primaries and secondaries.
6 | Includes power adjustment for each hue angle to adjust the strength: How much
7 | to distort chrominance near achromatic.
8 |
9 | Also includes a scale for each hue angle. This control scales the vector
10 | up and distorts towards the hue angle a bit. Effectively brightening or
11 | darkening the color while introducing small hue shifts towards or away
12 | from the hue angle in question.
13 |
14 | CMY hue angles also include control for offsetting the "center" of the hue angle.
15 | This can be useful for yellows for example, where you might want to place the
16 | center point slightly more towards orange-red than purely on the yellow secondary.
17 |
18 | The same control is not included for RGB because in my testing it was not needed.
19 |
20 | ---
21 | Written by Jed Smith
22 | github.com/jedypod/open-display-transform
23 | */
24 |
25 | DEFINE_UI_PARAMS(yp, yellow power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
26 | DEFINE_UI_PARAMS(y0, yellow shift 0: G->R, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
27 | DEFINE_UI_PARAMS(y1, yellow shift 1: G->R, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
28 | DEFINE_UI_PARAMS(ys, yellow scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
29 | DEFINE_UI_PARAMS(rp, red power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
30 | DEFINE_UI_PARAMS(r0, red shift 0: Y->M, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
31 | DEFINE_UI_PARAMS(r1, red shift 1: Y->M, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
32 | DEFINE_UI_PARAMS(rs, red scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
33 | DEFINE_UI_PARAMS(mp, magenta power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
34 | DEFINE_UI_PARAMS(m0, magenta shift 0: R->B, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
35 | DEFINE_UI_PARAMS(m1, magenta shift 1: R->B, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
36 | DEFINE_UI_PARAMS(ms, magenta scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
37 | DEFINE_UI_PARAMS(bp, blue power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
38 | DEFINE_UI_PARAMS(b0, blue shift 0: M->C, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
39 | DEFINE_UI_PARAMS(b1, blue shift 1: M->C, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
40 | DEFINE_UI_PARAMS(bs, blue scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
41 | DEFINE_UI_PARAMS(cp, cyan power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
42 | DEFINE_UI_PARAMS(c0, cyan shift 0: G->B, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
43 | DEFINE_UI_PARAMS(c1, cyan shift 1: G->B, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
44 | DEFINE_UI_PARAMS(cs, cyan scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
45 | DEFINE_UI_PARAMS(gp, green power, DCTLUI_SLIDER_FLOAT, 1, 0, 1, 0)
46 | DEFINE_UI_PARAMS(g0, green shift 0: C->Y, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
47 | DEFINE_UI_PARAMS(g1, green shift 1: C->Y, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
48 | DEFINE_UI_PARAMS(gs, green scale, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
49 | DEFINE_UI_PARAMS(cc, cyan center, DCTLUI_SLIDER_FLOAT, 0.25, -0.8, 0.8, 0)
50 | DEFINE_UI_PARAMS(mc, magenta center, DCTLUI_SLIDER_FLOAT, 0, -0.8, 0.8, 0)
51 | DEFINE_UI_PARAMS(yc, yellow center, DCTLUI_SLIDER_FLOAT, -0.25, -0.8, 0.8, 0)
52 |
53 |
54 | // Safe division of float a by float b
55 | __DEVICE__ float sdivf(float a, float b) {
56 | if (_fabs(b) < 0.0001f) return 0.0f;
57 | else return a / b;
58 | }
59 | // Safe division of float3 a by float b
60 | __DEVICE__ float3 sdivf3f(float3 a, float b) {
61 | return make_float3(sdivf(a.x, b), sdivf(a.y, b), sdivf(a.z, b));
62 | }
63 | // Safe power function raising float a to power float b
64 | __DEVICE__ float spowf(float a, float b) {
65 | if (a <= 0.0f) return a;
66 | else return _powf(a, b);
67 | }
68 | // Take the max of each component of float3 a and float b
69 | __DEVICE__ float3 maxf3(float3 a, float b) {
70 | return make_float3(_fmaxf(a.x, b), _fmaxf(a.y, b), _fmaxf(a.z, b));
71 | }
72 |
73 | // https://www.desmos.com/calculator/8tqz4rs0wm
74 | __DEVICE__ float power_window(float x, float c, float p0, float p1, float x0, float x1) {
75 | return x > x1 ? 0.0f : x > c ? _powf(1.0f - _powf((x - c)/(x1 - c), p0), p1) : x > x0 ? _powf(1.0f - _powf((c - x)/(c - x0), p0), p1) : 0.0f;
76 | }
77 |
78 |
79 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
80 | {
81 | float3 rgb = make_float3(p_R, p_G, p_B);
82 |
83 | // Calculate hue and "chroma"
84 | float mx = _fmaxf(rgb.x, _fmaxf(rgb.y, rgb.z));
85 | float mn = _fminf(rgb.x, _fminf(rgb.y, rgb.z));
86 | float ch = mx - mn;
87 | float h;
88 | if (ch == 0.0f) h = 0.0f;
89 | else if (mx == rgb.x) h = _fmod((rgb.y - rgb.z) / ch + 6.0f, 6.0f);
90 | else if (mx == rgb.y) h = (rgb.z - rgb.x) / ch + 2.0f;
91 | else if (mx == rgb.z) h = (rgb.x - rgb.y) / ch + 4.0f;
92 | ch = sdivf(ch, mx);
93 | // Clamp 0-4
94 | ch = _fmaxf(0.0f, _fminf(4.0f, ch));
95 |
96 | // "Half-Chroma" Norm: halfway between min and max of rgb
97 | float hch = mn*0.5f + mx*0.5f;
98 |
99 | // RGB Ratios
100 | rgb = sdivf3f(rgb, hch);
101 | rgb = maxf3(rgb, -2.0f);
102 |
103 | // Extract hue angles
104 | float hr = power_window(_fmod(h + 1.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, rp));
105 | float hg = power_window(_fmod(h + 5.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, gp));
106 | float hb = power_window(_fmod(h + 3.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, bp));
107 | float hc = power_window(_fmod(h + 4.0f, 6.0f), 1.0f+cc, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, cp));
108 | float hm = power_window(_fmod(h + 2.0f, 6.0f), 1.0f+mc, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, mp));
109 | float hy = power_window(_fmod(h + 0.0f, 6.0f), 1.0f+yc, 1.5f, 1.5f, 0.0f, 2.0f)*spowf(ch, 1.0f/_fmaxf(1e-5, yp));
110 |
111 | // Distort CMY hue angles
112 | rgb.x = (ms+1.0f)*(rgb.x-_fmaxf(0.0f,m0)-_fminf(0.0f,m1))*hm+(ys+1.0f)*(rgb.x+_fminf(0.0f,y0)+_fmaxf(0.0f,y1))*hy+rgb.x*(1.0f-(hm+hy));
113 | rgb.y = (cs+1.0f)*(rgb.y-_fmaxf(0.0f,c0)-_fminf(0.0f,c1))*hc+(ys+1.0f)*(rgb.y-_fmaxf(0.0f,y0)-_fminf(0.0f,y1))*hy+rgb.y*(1.0f-(hc+hy));
114 | rgb.z = (cs+1.0f)*(rgb.z+_fminf(0.0f,c0)+_fmaxf(0.0f,c1))*hc+(ms+1.0f)*(rgb.z+_fminf(0.0f,m0)+_fmaxf(0.0f,m1))*hm+rgb.z*(1.0f-(hc+hm));
115 |
116 | // Distort RGB hue angles
117 | rgb.x = (rs+1.0f)*rgb.x*hr+rgb.x*(1.0f+_fminf(0.0f,g0))*(1.0f+_fmaxf(0.0f,g1))*hg+rgb.x*(1.0f-_fmaxf(0.0f,b0))*(1.0f-_fminf(0.0f,b1))*hb+rgb.x*(1.0f-(hr+hg+hb));
118 | rgb.y = (gs+1.0f)*rgb.y*hg+rgb.y*(1.0f-_fmaxf(0.0f,r0))*(1.0f-_fminf(0.0f,r1))*hr+rgb.y*(1.0f+_fminf(0.0f,b0))*(1.0f+_fmaxf(0.0f,b1))*hb+rgb.y*(1.0f-(hr+hg+hb));
119 | rgb.z = (bs+1.0f)*rgb.z*hb+rgb.z*(1.0f+_fminf(0.0f,r0))*(1.0f+_fmaxf(0.0f,r1))*hr+rgb.z*(1.0f-_fmaxf(0.0f,g0))*(1.0f-_fminf(0.0f,g1))*hg+rgb.z*(1.0f-(hr+hg+hb));
120 |
121 | rgb *= hch;
122 | return rgb;
123 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/n6HueShift.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(sy, yellow, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
5 | DEFINE_UI_PARAMS(sr, red, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
6 | DEFINE_UI_PARAMS(sm, magenta, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
7 | DEFINE_UI_PARAMS(sb, blue, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
8 | DEFINE_UI_PARAMS(sc, cyan, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
9 | DEFINE_UI_PARAMS(sg, green, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
10 | DEFINE_UI_PARAMS(scu, custom, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
11 | DEFINE_UI_PARAMS(cuh, custom hue, DCTLUI_SLIDER_FLOAT, 100, 0, 360, 0)
12 | DEFINE_UI_PARAMS(cuw, custom width, DCTLUI_SLIDER_FLOAT, 0.3, 0, 2, 0)
13 | DEFINE_UI_PARAMS(str, strength, DCTLUI_SLIDER_FLOAT, 0.33, 0.1, 1, 0)
14 | DEFINE_UI_PARAMS(chl, chroma limit, DCTLUI_SLIDER_FLOAT, 0.33, 0, 1, 0)
15 | DEFINE_UI_PARAMS(ze, zone extract, DCTLUI_CHECK_BOX, 0)
16 | DEFINE_UI_PARAMS(zp, zone range, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
17 | DEFINE_UI_PARAMS(zone, zone, DCTLUI_COMBO_BOX, 1, {low, high}, {low, high})
18 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
19 |
20 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
21 | {
22 | float3 rgb = make_float3(p_R, p_G, p_B);
23 | rgb = linearize(rgb, tf, 0);
24 | int zr = 0;
25 | if (zone == high) zr = 1;
26 |
27 | rgb = n6_hueshift(rgb, sy, sr, sm, sb, sc, sg, scu, cuh, cuw, str, chl, ze, zp, zr);
28 | rgb = linearize(rgb, tf, 1);
29 | return rgb;
30 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/n6Purity.dctl:
--------------------------------------------------------------------------------
1 | /* n6Purity - v0.0.2
2 | -------------------------
3 | Another tool on the theme of "Vibrance".
4 | n6Purity adjusts the saturation of "mid-range" chroma values.
5 | The purity sliders adjust the saturation, and the strength sliders
6 | control how much of the chroma range to affect.
7 |
8 | ---
9 | Written by Jed Smith
10 | github.com/jedypod/open-display-transform
11 | */
12 |
13 | DEFINE_UI_PARAMS(rp, red purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
14 | DEFINE_UI_PARAMS(rs, red strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
15 | DEFINE_UI_PARAMS(gp, green purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
16 | DEFINE_UI_PARAMS(gs, green strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
17 | DEFINE_UI_PARAMS(bp, blue purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
18 | DEFINE_UI_PARAMS(bs, blue strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
19 | DEFINE_UI_PARAMS(cp, cyan purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
20 | DEFINE_UI_PARAMS(cs, cyan strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
21 | DEFINE_UI_PARAMS(mp, magenta purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
22 | DEFINE_UI_PARAMS(ms, magenta strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
23 | DEFINE_UI_PARAMS(yp, yellow purity, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
24 | DEFINE_UI_PARAMS(ys, yellow strength, DCTLUI_SLIDER_FLOAT, 2, 0, 4, 0)
25 |
26 | // Safe division of float a by float b
27 | __DEVICE__ float sdivf(float a, float b) {
28 | if (_fabs(b) < 0.0001f) return 0.0f;
29 | else return a / b;
30 | }
31 |
32 | // https://www.desmos.com/calculator/8tqz4rs0wm
33 | __DEVICE__ float power_window(float x, float c, float p0, float p1, float x0, float x1) {
34 | return x > x1 ? 0.0f : x > c ? _powf(1.0f - _powf((x - c)/(x1 - c), p0), p1) : x > x0 ? _powf(1.0f - _powf((c - x)/(c - x0), p0), p1) : 0.0f;
35 | }
36 |
37 | // https://www.desmos.com/calculator/bdbstdsvvv
38 | __DEVICE__ float pivoted_power_cubic(float x, float m, float p) {
39 | m = 1.0f - _fabs(m);
40 | float a0 = p*(m - 1.0f);
41 | float b0 = (1.0f - m)*(p + 1.0f);
42 | return x <= 0.0f ? m*x : x > 1.0f ? x : x*(_powf(x, p)*(a0*x + b0) + m);
43 | }
44 |
45 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
46 | {
47 | float3 rgb = make_float3(p_R, p_G, p_B);
48 |
49 | // Calculate hue and "chroma"
50 | float mx = _fmaxf(rgb.x, _fmaxf(rgb.y, rgb.z));
51 | float mn = _fminf(rgb.x, _fminf(rgb.y, rgb.z));
52 | float ch = mx - mn;
53 | float h;
54 | if (ch == 0.0f) h = 0.0f;
55 | else if (mx == rgb.x) h = _fmod((rgb.y - rgb.z) / ch + 6.0f, 6.0f);
56 | else if (mx == rgb.y) h = (rgb.z - rgb.x) / ch + 2.0f;
57 | else if (mx == rgb.z) h = (rgb.x - rgb.y) / ch + 4.0f;
58 | ch = sdivf(ch, mx);
59 |
60 | // Extract hue angles
61 | float hr = power_window(_fmod(h + 1.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
62 | float hg = power_window(_fmod(h + 5.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
63 | float hb = power_window(_fmod(h + 3.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
64 | float hc = power_window(_fmod(h + 4.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
65 | float hm = power_window(_fmod(h + 2.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
66 | float hy = power_window(_fmod(h + 0.0f, 6.0f), 1.0f, 1.5f, 1.5f, 0.0f, 2.0f);
67 |
68 | // Cubic chroma compression curve
69 | float cr = sdivf(rp < 0.0f ? pivoted_power_cubic(ch, rp, rs) : 1.0f - pivoted_power_cubic(1.0f - ch, rp, rs), ch);
70 | float cg = sdivf(gp < 0.0f ? pivoted_power_cubic(ch, gp, gs) : 1.0f - pivoted_power_cubic(1.0f - ch, gp, gs), ch);
71 | float cb = sdivf(bp < 0.0f ? pivoted_power_cubic(ch, bp, bs) : 1.0f - pivoted_power_cubic(1.0f - ch, bp, bs), ch);
72 | float cc = sdivf(cp < 0.0f ? pivoted_power_cubic(ch, cp, cs) : 1.0f - pivoted_power_cubic(1.0f - ch, cp, cs), ch);
73 | float cm = sdivf(mp < 0.0f ? pivoted_power_cubic(ch, mp, ms) : 1.0f - pivoted_power_cubic(1.0f - ch, mp, ms), ch);
74 | float cy = sdivf(yp < 0.0f ? pivoted_power_cubic(ch, yp, ys) : 1.0f - pivoted_power_cubic(1.0f - ch, yp, ys), ch);
75 |
76 |
77 | // Combine all hue angles to single chroma compression factor
78 | float chf = (hr*cr + hg*cg + hb*cb + (1.0f - (hr + hg + hb)))*(hc*cc + hm*cm + hy*cy + (1.0f - (hc + hm + hy)));
79 |
80 | // Weighted sum of RGB
81 | float wsum = rgb.x*0.3f + rgb.y*0.6f + rgb.z*0.1f;
82 |
83 | // Lerp towards wsum by chf
84 | float3 result = wsum*(1.0f - chf) + rgb*chf;
85 | return result;
86 | }
--------------------------------------------------------------------------------
/look-transforms/tools/resolve/n6Vibrance.dctl:
--------------------------------------------------------------------------------
1 | #line 2 // Fix line numbers in resolve/logs/rollinglog.txt
2 | #include "libLMT.h"
3 |
4 | DEFINE_UI_PARAMS(mgl, global, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
5 | DEFINE_UI_PARAMS(my, yellow, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
6 | DEFINE_UI_PARAMS(mr, red, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
7 | DEFINE_UI_PARAMS(mm, magenta, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
8 | DEFINE_UI_PARAMS(mb, blue, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
9 | DEFINE_UI_PARAMS(mc, cyan, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
10 | DEFINE_UI_PARAMS(mg, green, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
11 | DEFINE_UI_PARAMS(mcu, custom, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0)
12 | DEFINE_UI_PARAMS(cuh, hue, DCTLUI_SLIDER_FLOAT, 100, 0, 360, 0)
13 | DEFINE_UI_PARAMS(cuw, width, DCTLUI_SLIDER_FLOAT, 0.3, 0, 2, 0)
14 | DEFINE_UI_PARAMS(hl, hue-linear, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0)
15 | DEFINE_UI_PARAMS(ze, zone extract, DCTLUI_CHECK_BOX, 1)
16 | DEFINE_UI_PARAMS(zp, zone range, DCTLUI_SLIDER_FLOAT, 0, -4, 4, 0)
17 | DEFINE_UI_PARAMS(zone, zone, DCTLUI_COMBO_BOX, 0, {low, high}, {low, high})
18 | DEFINE_UI_PARAMS(tf, Transfer Function, DCTLUI_COMBO_BOX, 1, {ioetf_linear, ioetf_davinci_intermediate, ioetf_acescct, ioetf_arri_logc3, ioetf_arri_logc4, ioetf_redlog3g10}, {Linear, Davinci Intermediate, ACEScct, Arri LogC3, Arri LogC4, RedLog3G10})
19 |
20 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
21 | {
22 | float3 rgb = make_float3(p_R, p_G, p_B);
23 | rgb = linearize(rgb, tf, 0);
24 | int zr = 0;
25 | if (zone == high) zr = 1;
26 |
27 | rgb = n6_vibrance(rgb, mgl, my, mr, mm, mb, mc, mg, mcu, cuh, cuw, hl, ze, zp, zr);
28 | rgb = linearize(rgb, tf, 1);
29 | return rgb;
30 | }
--------------------------------------------------------------------------------
/utilities/GamutConvert.dctl:
--------------------------------------------------------------------------------
1 | #line 2
2 | /* GamutConvert
3 | Applies a pre-calculated 3x3 matrix to convert from in gamut to out gamut.
4 | */
5 |
6 | DEFINE_UI_PARAMS(ig, in gamut, DCTLUI_COMBO_BOX, 0, {i_xyz, i_ap0, i_ap1, i_p3d65, i_rec2020, i_rec709, i_awg3, i_awg4, i_rwg, i_sgamut3, i_sgamut3cine, i_vgamut, i_fgamutc, i_bmdwg, i_egamut, i_egamut2, i_davinciwg}, {XYZ, ACES 2065-1, ACEScg, P3D65, Rec.2020, Rec.709, Arri Wide Gamut 3, Arri Wide Gamut 4, Red Wide Gamut RGB, Sony SGamut3, Sony SGamut3Cine, Panasonic V-Gamut, Fujifilm F-GamutC, Blackmagic Wide Gamut, Filmlight E-Gamut, Filmlight E-Gamut2, DaVinci Wide Gamut})
7 | DEFINE_UI_PARAMS(og, out gamut, DCTLUI_COMBO_BOX, 0, {o_xyz, o_ap0, o_ap1, o_p3d65, o_rec2020, o_rec709, o_awg3, o_awg4, o_rwg, o_sgamut3, o_sgamut3cine, o_vgamut, o_fgamutc, o_bmdwg, o_egamut, o_egamut2, o_davinciwg}, {XYZ, ACES 2065-1, ACEScg, P3D65, Rec.2020, Rec.709, Arri Wide Gamut 3, Arri Wide Gamut 4, Red Wide Gamut RGB, Sony SGamut3, SGamut3Cine, Panasonic V-Gamut, Fujifilm F-GamutC, Blackmagic Wide Gamut, Filmlight E-Gamut, Filmlight E-Gamut2, DaVinci Wide Gamut})
8 | // DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0)
9 |
10 |
11 | // Struct for a 3x3 matrix
12 | typedef struct {
13 | float3 x, y, z;
14 | } float3x3;
15 |
16 | // Helper function to create a float3x3
17 | __DEVICE__ float3x3 make_float3x3(float3 a, float3 b, float3 c) {
18 | float3x3 d;
19 | d.x = a, d.y = b, d.z = c;
20 | return d;
21 | }
22 |
23 | // Multiply 3x3 matrix m and float3 vector v
24 | __DEVICE__ float3 vdot(float3x3 m, float3 v) {
25 | return make_float3(m.x.x*v.x + m.x.y*v.y + m.x.z*v.z, m.y.x*v.x + m.y.y*v.y + m.y.z*v.z, m.z.x*v.x + m.z.y*v.y + m.z.z*v.z);
26 | }
27 |
28 |
29 |
30 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
31 | {
32 | // Get the input RGB
33 | float3 rgb = make_float3(p_R, p_G, p_B);
34 |
35 | // If in gamut equals out gamut, do nothing
36 | if (ig == og) return rgb;
37 |
38 |
39 | float3x3 imtx;
40 | // Match in-gamut to the right matrix
41 | if (ig == i_ap0) imtx = make_float3x3(make_float3(0.93863094875f, -0.00574192055f, 0.017566898852f), make_float3(0.338093594922f, 0.727213902811f, -0.065307497733f), make_float3(0.000723121511f, 0.000818441849f, 1.0875161874f));
42 | else if (ig == i_ap1) imtx = make_float3x3(make_float3(0.652418717672f, 0.127179925538f, 0.170857283842f), make_float3(0.268064059194f, 0.672464478993f, 0.059471461813f), make_float3(-0.00546992851f, 0.005182799977f, 1.08934487929f));
43 | else if (ig == i_p3d65) imtx = make_float3x3(make_float3(0.486570948648f, 0.265667693169f, 0.198217285234f), make_float3(0.22897456407f, 0.691738521837f, 0.079286914094f), make_float3(-0.0f, 0.045113381859f, 1.0439443689f));
44 | else if (ig == i_rec2020) imtx = make_float3x3(make_float3(0.636958048301f, 0.144616903586f, 0.168880975164f), make_float3(0.262700212011f, 0.677998071519f, 0.05930171647f), make_float3(0.0f, 0.028072693049f, 1.06098505771f));
45 | else if (ig == i_rec709) imtx = make_float3x3(make_float3(0.412390799266f, 0.357584339384f, 0.180480788402f), make_float3(0.212639005872f, 0.715168678768f, 0.072192315361f), make_float3(0.019330818716f, 0.119194779795f, 0.95053215225f));
46 | else if (ig == i_awg3) imtx = make_float3x3(make_float3(0.638007619284f, 0.214703856337f, 0.097744451431f), make_float3(0.291953779f, 0.823841041511f, -0.11579482051f), make_float3(0.002798279032f, -0.067034235689f, 1.15329370742f));
47 | else if (ig == i_awg4) imtx = make_float3x3(make_float3(0.704858320407f, 0.12976029517f, 0.115837311474f), make_float3(0.254524176404f, 0.781477732712f, -0.036001909116f), make_float3(0.0f, 0.0f, 1.08905775076f));
48 | else if (ig == i_rwg) imtx = make_float3x3(make_float3(0.735275245906f, 0.068609410614f, 0.146571270532f), make_float3(0.2866940995f, 0.842979134017f, -0.129673233517f), make_float3(-0.079680856878f, -0.347343216994f, 1.51608182463f));
49 | else if (ig == i_sgamut3) imtx = make_float3x3(make_float3(0.706482713192f, 0.128801049791f, 0.115172164069f), make_float3(0.270979670813f, 0.786606411221f, -0.057586082034f), make_float3(-0.009677845386f, 0.004600037493f, 1.09413555865f));
50 | else if (ig == i_sgamut3cine) imtx = make_float3x3(make_float3(0.599083920758f, 0.248925516115f, 0.102446490178f), make_float3(0.215075820116f, 0.885068501744f, -0.100144321859f), make_float3(-0.032065849545f, -0.027658390679f, 1.14878199098f));
51 | else if (ig == i_vgamut) imtx = make_float3x3(make_float3(0.679644469878f, 0.15221141244f, 0.118600044733f), make_float3(0.26068555009f, 0.77489446333f, -0.03558001342f), make_float3(-0.009310198218f, -0.004612467044f, 1.10298041602f));
52 | else if (ig == i_fgamutc) imtx = make_float3x3(make_float3(0.789274967789f, 0.02004022988f, 0.141140729383f), make_float3(0.285007008241f, 0.741945697114f, -0.026952705355f), make_float3(0.0f, 0.0f, 1.08905775076f));
53 | else if (ig == i_bmdwg) imtx = make_float3x3(make_float3(0.606538368283f, 0.220412735329f, 0.12350482344f), make_float3(0.267992940057f, 0.832748409123f, -0.10074134918f), make_float3(-0.02944255416f, -0.086612430277f, 1.2051127352f));
54 | else if (ig == i_egamut) imtx = make_float3x3(make_float3(0.705396850088f, 0.16404132831f, 0.081017748654f), make_float3(0.280130724091f, 0.82020664155f, -0.100337365641f), make_float3(-0.103781511569f, -0.072907257027f, 1.26574651936f));
55 | else if (ig == i_egamut2) imtx = make_float3x3(make_float3(0.736477700184f, 0.130739651087f, 0.083238575781f), make_float3(0.275069984406f, 0.828017790216f, -0.103087774621f), make_float3(-0.124225154248f, -0.087159767391f, 1.3004426724f));
56 | else if (ig == i_davinciwg) imtx = make_float3x3(make_float3(0.700622392094f, 0.148774815123f, 0.101058719835f), make_float3(0.274118510907f, 0.87363189594f, -0.147750406847f), make_float3(-0.098962912883f, -0.137895325076f, 1.32591598872f));
57 |
58 | float3x3 omtx;
59 | // Match out-gamut to the right matrix
60 | if (og == o_ap0) omtx = make_float3x3(make_float3(1.06236610705f, 0.008406953654f, -0.016655789633f), make_float3(-0.493941371628f, 1.37110952521f, 0.090316586974f), make_float3(-0.000334668577f, -0.001037458272f, 0.919469647322f));
61 | else if (og == o_ap1) omtx = make_float3x3(make_float3(1.65885430847f, -0.311856975397f, -0.243156007126f), make_float3(-0.662283287108f, 1.61219957087f, 0.015859126603f), make_float3(0.011480566457f, -0.009236324924f, 0.916686513449f));
62 | else if (og == o_p3d65) omtx = make_float3x3(make_float3(2.49349691194f, -0.931383617919f, -0.402710784451f), make_float3(-0.829488969562f, 1.76266406032f, 0.023624685842f), make_float3(0.035845830244f, -0.076172389268f, 0.956884524008f));
63 | else if (og == o_rec2020) omtx = make_float3x3(make_float3(1.71665118797f, -0.355670783776f, -0.253366281374f), make_float3(-0.666684351832f, 1.61648123664f, 0.015768545814f), make_float3(0.017639857445f, -0.042770613258f, 0.942103121235f));
64 | else if (og == o_rec709) omtx = make_float3x3(make_float3(3.2409699419f, -1.53738317757f, -0.498610760293f), make_float3(-0.969243636281f, 1.87596750151f, 0.041555057407f), make_float3(0.055630079697f, -0.203976958889f, 1.05697151424f));
65 | else if (og == o_awg3) omtx = make_float3x3(make_float3(1.78906555097f, -0.482533863771f, -0.200075792936f), make_float3(-0.639848659902f, 1.39639995686f, 0.194432291778f), make_float3(-0.041531545853f, 0.082335373554f, 0.878868480293f));
66 | else if (og == o_awg4) omtx = make_float3x3(make_float3(1.50921547224f, -0.250597345204f, -0.168811475294f), make_float3(-0.491545451661f, 1.36124554593f, 0.097282942014f), make_float3(0.0f, 0.0f, 0.918224951158f));
67 | else if (og == o_rwg) omtx = make_float3x3(make_float3(1.41280648037f, -0.17752320099f, -0.151770732029f), make_float3(-0.48620327686f, 1.2906964268f, 0.15740061473f), make_float3(-0.037139010853f, 0.286375999779f, 0.687679778862f));
68 | else if (og == o_sgamut3) omtx = make_float3x3(make_float3(1.50739989906f, -0.245822137385f, -0.171611680816f), make_float3(-0.518151727083f, 1.3553912409f, 0.125878668162f), make_float3(0.015511698158f, -0.007872771427f, 0.911916365575f));
69 | else if (og == o_sgamut3cine) omtx = make_float3x3(make_float3(1.84677896929f, -0.525986122969f, -0.210545211388f), make_float3(-0.444153262903f, 1.25944290281f, 0.149399972888f), make_float3(0.040855421196f, 0.01564088931f, 0.868207248699f));
70 | else if (og == o_vgamut) omtx = make_float3x3(make_float3(1.58901177387f, -0.31320448446f, -0.180964851528f), make_float3(-0.534052910449f, 1.39601143335f, 0.102457671017f), make_float3(0.011179448843f, 0.003194128241f, 0.905535356281f));
71 | else if (og == o_fgamutc) omtx = make_float3x3(make_float3(1.27946475834f, -0.034558820113f, -0.166672559633f), make_float3(-0.491486673948f, 1.36108277177f, 0.0973811081f), make_float3(0.0f, 0.0f, 0.918224951158f));
72 | else if (og == o_bmdwg) omtx = make_float3x3(make_float3(1.86635773561f, -0.518390508775f, -0.234606716542f), make_float3(-0.600329854462f, 1.37811995056f, 0.176728109838f), make_float3(0.002451481064f, 0.086381609339f, 0.836767715319f));
73 | else if (og == o_egamut) omtx = make_float3x3(make_float3(1.52505277041f, -0.315913510935f, -0.122658264605f), make_float3(-0.509152559971f, 1.33332740873f, 0.138284365141f), make_float3(0.095715345314f, 0.050897443852f, 0.787955770285f));
74 | else if (og == o_egamut2) omtx = make_float3x3(make_float3(1.42776075557f, -0.237033581941f, -0.110177895085f), make_float3(-0.461174449232f, 1.2944289444f, 0.13212985645f), make_float3(0.105477884785f, 0.064114008399f, 0.767299906963f));
75 | else if (og == o_davinciwg) omtx = make_float3x3(make_float3(1.51667204202f, -0.281478047879f, -0.146963633237f), make_float3(-0.464917101233f, 1.25142377568f, 0.174884608865f), make_float3(0.064849047067f, 0.109139343711f, 0.76141462155f));
76 |
77 |
78 |
79 | if (ig != i_xyz) {
80 | // Apply in gamut to XYZ conversion
81 | rgb = vdot(imtx, rgb);
82 | }
83 | if (og != o_xyz) {
84 | // Apply XYZ to out gamut conversion
85 | rgb = vdot(omtx, rgb);
86 | }
87 |
88 | return rgb;
89 | }
90 |
--------------------------------------------------------------------------------
/utilities/GamutConvertFull.dctl:
--------------------------------------------------------------------------------
1 | #line 2
2 | /* GamutConvert
3 | Calculate a 3x3 matrix to convert between two gamuts.
4 |
5 | Includes a Chromatic Adaptation Transform (CAT) if the whitepoint of gamut A does not match gamut B.
6 | Does not rely on predefined matrices. Calculates the gamut conversion matrix at machine precision,
7 | using the RGBW chromaticity coordinates of the gamut.
8 |
9 | */
10 |
11 | DEFINE_UI_PARAMS(ig, in gamut, DCTLUI_COMBO_BOX, 0, {i_xyz, i_xyz_d65, i_ap0, i_ap1, i_p3d65, i_rec2020, i_rec709, i_awg3, i_awg4, i_rwg, i_sgamut3, i_sgamut3cine, i_vgamut, i_bmdwg, i_egamut, i_egamut2, i_davinciwg}, {XYZ, XYZ D65, ACES 2065-1, ACEScg, P3D65, Rec.2020, Rec.709, Arri Wide Gamut 3, Arri Wide Gamut 4, Red Wide Gamut RGB, Sony SGamut3, Sony SGamut3Cine, Panasonic V-Gamut, Blackmagic Wide Gamut, Filmlight E-Gamut, Filmlight E-Gamut2, DaVinci Wide Gamut})
12 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0);
13 | DEFINE_UI_PARAMS(og, out gamut, DCTLUI_COMBO_BOX, 0, {o_xyz, o_xyz_d65, o_ap0, o_ap1, o_p3d65, o_rec2020, o_rec709, o_awg3, o_awg4, o_rwg, o_sgamut3, o_sgamut3cine, o_vgamut, o_bmdwg, o_egamut, o_egamut2, o_davinciwg}, {XYZ, XYZ D65, ACES 2065-1, ACEScg, P3D65, Rec.2020, Rec.709, Arri Wide Gamut 3, Arri Wide Gamut 4, Red Wide Gamut RGB, Sony SGamut3, SGamut3Cine, Panasonic V-Gamut, Blackmagic Wide Gamut, Filmlight E-Gamut, Filmlight E-Gamut2, DaVinci Wide Gamut})
14 |
15 | // Struct for a 3x3 matrix
16 | typedef struct {
17 | float3 x, y, z;
18 | } float3x3;
19 |
20 | // chromaticity coordinates for primaries and whitepoint of an rgb gamut
21 | typedef struct {
22 | float2 r, g, b, w;
23 | } chr;
24 |
25 | // Helper function to create a float3x3
26 | __DEVICE__ float3x3 make_float3x3(float3 a, float3 b, float3 c) {
27 | float3x3 d;
28 | d.x = a, d.y = b, d.z = c;
29 | return d;
30 | }
31 |
32 | // Helper function to create a chr chromaticities object
33 | __DEVICE__ chr make_chr(float2 r, float2 g, float2 b, float2 w) {
34 | chr c;
35 | c.r = r, c.g = g, c.b = b, c.w = w;
36 | return c;
37 | }
38 |
39 | // Return 3x3 matrix filled with zeros
40 | __DEVICE__ float3x3 zeros() {
41 | return make_float3x3(make_float3(0.0f, 0.0f, 0.0f), make_float3(0.0f, 0.0f, 0.0f), make_float3(0.0f, 0.0f, 0.0f));
42 | }
43 |
44 | // set diagonal row of 3x3 matrix m to float3 v
45 | __DEVICE__ float3x3 diag(float3x3 m, float3 v) {
46 | m.x.x = v.x;
47 | m.y.y = v.y;
48 | m.z.z = v.z;
49 | return m;
50 | }
51 |
52 | // Return identity 3x3 matrix
53 | __DEVICE__ float3x3 identity() {
54 | return diag(zeros(), make_float3(1.0f, 1.0f, 1.0f));
55 | }
56 |
57 | // Multiply 3x3 matrix m and float3 vector v
58 | __DEVICE__ float3 vdot(float3x3 m, float3 v) {
59 | return make_float3(m.x.x*v.x + m.x.y*v.y + m.x.z*v.z, m.y.x*v.x + m.y.y*v.y + m.y.z*v.z, m.z.x*v.x + m.z.y*v.y + m.z.z*v.z);
60 | }
61 |
62 | // transpose 3x3 matrix m by swapping rows and columns
63 | __DEVICE__ float3x3 transpose(float3x3 a) {
64 | float3x3 m = zeros();
65 | m.x = make_float3(a.x.x, a.y.x, a.z.x);
66 | m.y = make_float3(a.x.y, a.y.y, a.z.y);
67 | m.z = make_float3(a.x.z, a.y.z, a.z.z);
68 | return m;
69 | }
70 |
71 | // Multiply 3x3 matrix a with 3x3 matrix b
72 | __DEVICE__ float3x3 matmul(float3x3 a, float3x3 b) {
73 | float3x3 c = zeros();
74 | c.x.x = a.x.x*b.x.x + a.x.y*b.y.x + a.x.z*b.z.x;
75 | c.x.y = a.x.x*b.x.y + a.x.y*b.y.y + a.x.z*b.z.y;
76 | c.x.z = a.x.x*b.x.z + a.x.y*b.y.z + a.x.z*b.z.z;
77 | c.y.x = a.y.x*b.x.x + a.y.y*b.y.x + a.y.z*b.z.x;
78 | c.y.y = a.y.x*b.x.y + a.y.y*b.y.y + a.y.z*b.z.y;
79 | c.y.z = a.y.x*b.x.z + a.y.y*b.y.z + a.y.z*b.z.z;
80 | c.z.x = a.z.x*b.x.x + a.z.y*b.y.x + a.z.z*b.z.x;
81 | c.z.y = a.z.x*b.x.y + a.z.y*b.y.y + a.z.z*b.z.y;
82 | c.z.z = a.z.x*b.x.z + a.z.y*b.y.z + a.z.z*b.z.z;
83 | return c;
84 | }
85 |
86 | // Calculate inverse of 3x3 matrix: https://stackoverflow.com/questions/983999/simple-3x3-matrix-inverse-code-c
87 | __DEVICE__ float3x3 inv(float3x3 m) {
88 | float3x3 c = identity();
89 | float d = m.x.x*(m.y.y*m.z.z - m.z.y*m.y.z) -
90 | m.x.y*(m.y.x*m.z.z - m.y.z*m.z.x) +
91 | m.x.z*(m.y.x*m.z.y - m.y.y*m.z.x);
92 | if (d == 0.0f) return c; // No Inverse
93 | float id = 1.0f/d;
94 | c.x.x = id*(m.y.y*m.z.z - m.z.y*m.y.z);
95 | c.x.y = id*(m.x.z*m.z.y - m.x.y*m.z.z);
96 | c.x.z = id*(m.x.y*m.y.z - m.x.z*m.y.y);
97 | c.y.x = id*(m.y.z*m.z.x - m.y.x*m.z.z);
98 | c.y.y = id*(m.x.x*m.z.z - m.x.z*m.z.x);
99 | c.y.z = id*(m.y.x*m.x.z - m.x.x*m.y.z);
100 | c.z.x = id*(m.y.x*m.z.y - m.z.x*m.y.y);
101 | c.z.y = id*(m.z.x*m.x.y - m.x.x*m.z.y);
102 | c.z.z = id*(m.x.x*m.y.y - m.y.x*m.x.y);
103 | return c;
104 | }
105 |
106 | /* Calculate the Normalized Primaries Matrix for the specified chromaticities
107 | Adapted from RP 177:1993
108 | SMPTE Recommended Practice - Derivation of Basic Television Color Equations
109 | http://doi.org/10.5594/S9781614821915
110 | https://mega.nz/file/frAnCIYK#CNRW5Q99G-w_QZtv5ey_0AkRWNrQVh7bM70kVwv42NQ
111 | */
112 | __DEVICE__ float3x3 npm(chr p) {
113 | float3x3 P = zeros();
114 | P.x = make_float3(p.r.x, p.r.y, 1.0f - p.r.x - p.r.y);
115 | P.y = make_float3(p.g.x, p.g.y, 1.0f - p.g.x - p.g.y);
116 | P.z = make_float3(p.b.x, p.b.y, 1.0f - p.b.x - p.b.y);
117 | P = transpose(P);
118 | float3 W = make_float3(p.w.x, p.w.y, 1.0f - p.w.x - p.w.y);
119 | W = make_float3(W.x / W.y, 1.0f, W.z / W.y);
120 | float3 C = vdot(inv(P), W);
121 | float3x3 M = diag(zeros(), C);
122 | return matmul(P, M);
123 | }
124 |
125 | // Convert xy chromaticity coordinate to XYZ tristimulus with Y=1.0
126 | __DEVICE__ float3 xy_to_XYZ(float2 xy) {
127 | return make_float3(xy.x/xy.y, 1.0f, (1.0f - xy.x - xy.y)/xy.y);
128 | }
129 |
130 | /* Calculate a von Kries style chromatic adaptation matrix
131 | given xy chromaticities for source white (ws) and destination white (wd)
132 | Source: Mark D. Fairchild - 2013 - Color Appearance Models Third Edition p. 181-186
133 | Source: Bruce Lindbloom - Chromatic Adaptation - http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
134 | */
135 | __DEVICE__ float3x3 cat(float2 ws, float2 wd, int method) {
136 | if (ws.x == wd.x && ws.y == wd.y) return identity(); // Whitepoints are equal, nothing to do
137 | float3x3 mcat = identity();
138 | if (method == 0) { // CAT02
139 | mcat = make_float3x3(make_float3(0.7328f, 0.4296f, -0.1624f), make_float3(-0.7036f, 1.6975f, 0.0061f), make_float3(0.003f, 0.0136f, 0.9834f));
140 | } else if (method == 1) { // Bradford
141 | mcat = make_float3x3(make_float3(0.8951f, 0.2664f, -0.1614f), make_float3(-0.7502f, 1.7135f, 0.0367f), make_float3(0.0389f, -0.0685f, 1.0296f));
142 | }
143 |
144 | float3 sXYZ = xy_to_XYZ(ws); // source normalized XYZ
145 | float3 dXYZ = xy_to_XYZ(wd); // destination normalized XYZ
146 |
147 | float3 sm = vdot(mcat, sXYZ); // source mult
148 | float3 dm = vdot(mcat, dXYZ); // destination mult
149 |
150 | float3x3 smat = diag(zeros(), make_float3(dm.x/sm.x, dm.y/sm.y, dm.z/sm.z));
151 | float3x3 nmat = matmul(inv(mcat), smat);
152 | return matmul(nmat, mcat);
153 | }
154 |
155 | // Calculate 3x3 matrix to convert from source rgb gamut to destination rgb gamut
156 | // Include CAT if whitepoints are different.
157 | __DEVICE__ float3x3 rgb_to_rgb(chr ch0, chr ch1) {
158 | float3x3 rgb0_to_xyz = npm(ch0);
159 | float3x3 rgb1_to_xyz = npm(ch1);
160 | float3x3 xyz_to_cat = cat(ch0.w, ch1.w, 0);
161 | float3x3 rgb0_to_cat = matmul(xyz_to_cat, rgb0_to_xyz);
162 | float3x3 rgb0_to_rgb1 = matmul(inv(rgb1_to_xyz), rgb0_to_cat);
163 | return rgb0_to_rgb1;
164 | }
165 |
166 | // Calculate 3x3 matrix to convert from source rgb gamut ch to XYZ with CAT
167 | __DEVICE__ float3x3 rgb_to_XYZ_cat(chr ch, float2 wd) {
168 | float3x3 rgb_to_xyz = npm(ch);
169 | if (ch.w.x == wd.x && ch.w.y == wd.y) return rgb_to_xyz; // No CAT needed.
170 | float3x3 cat_mtx = cat(ch.w, wd, 0);
171 | return matmul(cat_mtx, rgb_to_xyz);
172 | }
173 |
174 |
175 |
176 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
177 | {
178 | // Chromaticity coordinates for various whitepoints
179 | float2 wp_ACES = make_float2(0.32168f, 0.33767f);
180 | float2 wp_D60 = make_float2(0.321626f, 0.337737f);
181 | float2 wp_D65 = make_float2(0.3127f, 0.329f);
182 | float2 wp_DCI = make_float2(0.314f, 0.351f);
183 | float2 wp_E = make_float2(0.333333f, 0.333333f);
184 |
185 | // Chromaticity coordinates for various gamuts
186 | chr ap0 = make_chr(make_float2(0.7347f, 0.2653f), make_float2(0.0f, 1.0f), make_float2(0.0001f, -0.077f), wp_ACES);
187 | chr ap1 = make_chr(make_float2(0.713f, 0.293f), make_float2(0.165f, 0.83f), make_float2(0.128f, 0.044f), wp_ACES);
188 | chr bdgamut = make_chr(make_float2(0.8150f, 0.3167f), make_float2(0.2036f, 0.8500f), make_float2(0.0517f, -0.1026f), wp_D65);
189 | chr egamut = make_chr(make_float2(0.8f, 0.3177f), make_float2(0.18f, 0.9f), make_float2(0.065f, -0.0805f), wp_D65);
190 | chr egamut2 = make_chr(make_float2(0.83f, 0.31f), make_float2(0.15f, 0.95f), make_float2(0.065f, -0.0805f), wp_D65);
191 | chr davinciwg = make_chr(make_float2(0.8f, 0.313f), make_float2(0.1682f, 0.9877f), make_float2(0.079f, -0.1155f), wp_D65);
192 | chr rec709 = make_chr(make_float2(0.64f, 0.33f), make_float2(0.3f, 0.6f), make_float2(0.15f, 0.06f), wp_D65);
193 | chr rec2020 = make_chr(make_float2(0.708f, 0.292f), make_float2(0.17f, 0.797f), make_float2(0.131f, 0.046f), wp_D65);
194 | chr p3d60 = make_chr(make_float2(0.68f, 0.32f), make_float2(0.265f, 0.69f), make_float2(0.15f, 0.06f), wp_D60);
195 | chr p3d65 = make_chr(make_float2(0.68f, 0.32f), make_float2(0.265f, 0.69f), make_float2(0.15f, 0.06f), wp_D65);
196 | chr p3dci = make_chr(make_float2(0.68f, 0.32f), make_float2(0.265f, 0.69f), make_float2(0.15f, 0.06f), wp_DCI);
197 | chr awg3 = make_chr(make_float2(0.684f, 0.313f), make_float2(0.221f, 0.848f), make_float2(0.0861f, -0.102f), wp_D65);
198 | chr awg4 = make_chr(make_float2(0.7347f, 0.2653f), make_float2(0.1424f, 0.8576f), make_float2(0.0991f, -0.0308f), wp_D65);
199 | chr rwg = make_chr(make_float2(0.780308f, 0.304253f), make_float2(0.121595f, 1.493994f), make_float2(0.095612f, -0.084589f), wp_D65);
200 | chr protune = make_chr(make_float2(0.69848046f, 0.19302645f), make_float2(0.32955538f, 1.02459662f), make_float2(0.10844263f, -0.03467857f), wp_D65);
201 | chr cgamut = make_chr(make_float2(0.74f, 0.27f), make_float2(0.17f, 1.14f), make_float2(0.08f, -0.1f), wp_D65);
202 | chr sgamut3 = make_chr(make_float2(0.73f, 0.28f), make_float2(0.14f, 0.855f), make_float2(0.1f, -0.05f), wp_D65);
203 | chr sgamut3cine = make_chr(make_float2(0.766f, 0.275f), make_float2(0.225f, 0.8f), make_float2(0.089f, -0.087f), wp_D65);
204 | chr vgamut = make_chr(make_float2(0.73f, 0.28f), make_float2(0.165f, 0.84f), make_float2(0.1f, -0.03f), wp_D65);
205 | chr dgamut = make_chr(make_float2(0.71f, 0.31f), make_float2(0.21f, 0.88f), make_float2(0.09f, -0.08f), wp_D65);
206 | chr bmdwg = make_chr(make_float2(0.7177215f, 0.3171181f), make_float2(0.228041f, 0.861569f), make_float2(0.1005841f, -0.0820452f), wp_D65);
207 | chr adobergb = make_chr(make_float2(0.64f, 0.33f), make_float2(0.21f, 0.71f), make_float2(0.15f, 0.06f), wp_D65);
208 |
209 |
210 | chr ichr; // input chromaticities
211 | // Match in-gamut to the right chromaticities
212 | if (ig == i_ap0) ichr = ap0;
213 | else if (ig == i_ap1) ichr = ap1;
214 | else if (ig == i_p3d65) ichr = p3d65;
215 | else if (ig == i_rec2020) ichr = rec2020;
216 | else if (ig == i_rec709) ichr = rec709;
217 | else if (ig == i_awg3) ichr = awg3;
218 | else if (ig == i_awg4) ichr = awg4;
219 | else if (ig == i_rwg) ichr = rwg;
220 | else if (ig == i_sgamut3) ichr = sgamut3;
221 | else if (ig == i_sgamut3cine) ichr = sgamut3cine;
222 | else if (ig == i_vgamut) ichr = vgamut;
223 | else if (ig == i_bmdwg) ichr = bmdwg;
224 | else if (ig == i_egamut) ichr = egamut;
225 | else if (ig == i_egamut2) ichr = egamut2;
226 | else if (ig == i_davinciwg) ichr = davinciwg;
227 |
228 | chr ochr; // output chromaticities
229 | // Match out-gamut to the right chromaticities
230 | if (og == o_ap0) ochr = ap0;
231 | else if (og == o_ap1) ochr = ap1;
232 | else if (og == o_p3d65) ochr = p3d65;
233 | else if (og == o_rec2020) ochr = rec2020;
234 | else if (og == o_rec709) ochr = rec709;
235 | else if (og == o_awg3) ochr = awg3;
236 | else if (og == o_awg4) ochr = awg4;
237 | else if (og == o_rwg) ochr = rwg;
238 | else if (og == o_sgamut3) ochr = sgamut3;
239 | else if (og == o_sgamut3cine) ochr = sgamut3cine;
240 | else if (og == o_vgamut) ochr = vgamut;
241 | else if (og == o_bmdwg) ochr = bmdwg;
242 | else if (og == o_egamut) ochr = egamut;
243 | else if (og == o_egamut2) ochr = egamut2;
244 | else if (og == o_davinciwg) ochr = davinciwg;
245 |
246 |
247 | // Get the input RGB and calculate the matrix.
248 | float3 rgb = make_float3(p_R, p_G, p_B);
249 |
250 | float3x3 mtx = identity();
251 |
252 | mtx = npm(ichr);
253 |
254 | // If in gamut equals out gamut, do nothing
255 | if (ig == og) return rgb;
256 |
257 | // If in-gamut is XYZ: mtx is inverse of out-gamut to XYZ. (No chromatic adaptation transform!)
258 | // If out-gamut is XYZ: mtx is in-gamut to XYZ.
259 | // Otherwise, calculate a full rgb to rgb conversion matrix.
260 | if (ig == i_xyz) mtx = inv(npm(ochr));
261 | else if (ig == i_xyz_d65) mtx = inv(rgb_to_XYZ_cat(ochr, wp_D65));
262 | else if (og == o_xyz) mtx = npm(ichr);
263 | else if (og == o_xyz_d65) mtx = rgb_to_XYZ_cat(ichr, wp_D65);
264 | else mtx = rgb_to_rgb(ichr, ochr);
265 |
266 | if (invert == 1) mtx = inv(mtx);
267 |
268 | // Apply the matrix to RGB with a vector dot-product.
269 | rgb = vdot(mtx, rgb);
270 |
271 | return rgb;
272 | }
273 |
--------------------------------------------------------------------------------
/utilities/LogConvert.dctl:
--------------------------------------------------------------------------------
1 | /* LogConvert
2 | ------------------
3 | Converts from linear to log and back.
4 |
5 | */
6 |
7 | DEFINE_UI_PARAMS(curve, curve, DCTLUI_COMBO_BOX, 0, {acescc, acescct, arri_logc3, arri_logc4, blackmagic_filmgen5, canon_clog2, canon_clog3, dji_dlog, fujifilm_flog, fujifilm_flog2, gopro_protune, leica_llog, nikon_nlog, panasonic_vlog, red_log3g10, sony_slog2, sony_slog3, davinci_intermediate, filmlight_tlog, kodak_cineon}, {ACEScc, ACEScct, Arri LogC3, Arri LogC4, Blackmagic Film Gen5, Canon CLog2, Canon CLog3, DJI DLog, Fujifilm FLog, Fujifilm FLog2, GoPro ProTune, Leica LLog, Nikon NLog, Panasonic VLog, Red Log3G10, Sony SLog2, Sony SLog3, DaVinci Intermediate, Filmlight TLog, Kodak Cineon})
8 | DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0);
9 |
10 |
11 | __DEVICE__ float oetf_acescc(float x, int inv) {
12 | /* ACEScc Log
13 | S-2014-003 : ACEScc - A Quasi-Logarithmic Encoding of ACES Data for use within Color Grading Systems
14 | http://j.mp/S-2014-003
15 | */
16 | const float A = 9.72f;
17 | const float B = 17.52f;
18 |
19 | if (inv == 1) {
20 | return x <= (A - 15.0f)/B ? (_powf(2.0f, x*B - A) - _powf(2.0f, -16.0f))*2.0f : x < (_log2f(65504.0f) + A)/B ? _powf(2.0f, x*B - A) : x;
21 | } else {
22 | return x <= 0.0f ? (_log2f(-16.0f) + A)/B : x < _powf(2.0f, -15.0f) ? (_log2f(_powf(2.0f, -16.0f) + x/2.0f) + A)/B : (_log2f(x) + A)/B;
23 | }
24 | }
25 |
26 |
27 | __DEVICE__ float oetf_acescct(float x, int inv) {
28 | /* ACEScct Log
29 | S-2016-001 : ACEScct - A Quasi-Logarithmic Encoding of ACES Data for use within Color Grading Systems
30 | http://j.mp/S-2016-001_
31 | */
32 | const float cut1 = 0.0078125f;
33 | const float cut2 = 0.155251141552511f;
34 | const float A = 10.5402377416545f;
35 | const float B = 0.0729055341958355f;
36 | const float C = 9.72f;
37 | const float D = 17.52f;
38 |
39 | if (inv == 1) {
40 | return x <= cut2 ? (x - B)/A : _exp2f(x*D - C);
41 | } else {
42 | return x <= cut1 ? A*x + B : (_log2f(x) + C)/D;
43 | }
44 | }
45 |
46 | __DEVICE__ float oetf_arri_logc3(float x, int inv) {
47 | /* Arri Alexa LogC3
48 | Formerly known as Alexa V3LogC EI800
49 | https://www.arri.com/resource/blob/31918/66f56e6abb6e5b6553929edf9aa7483e/2017-03-alexa-logc-curve-in-vfx-data.pdf
50 | */
51 |
52 | const float cut = 0.010591f;
53 | const float a = 5.555556f;
54 | const float b = 0.052272f;
55 | const float c = 0.247190f;
56 | const float d = 0.385537f;
57 | const float e = 5.367655f;
58 | const float f = 0.092809f;
59 |
60 | if (inv == 1) {
61 | return x < e*cut + f ? (x - f)/e : (_exp10f((x - d)/c) - b)/a;
62 | } else {
63 | return x < cut ? e*x + f : c*_log10f(a*x + b) + d;
64 | }
65 | }
66 |
67 | __DEVICE__ float oetf_arri_logc4(float x, int inv) {
68 | /* Arri Alexa LogC4
69 | https://www.arri.com/resource/blob/278790/bea879ac0d041a925bed27a096ab3ec2/2022-05-arri-logc4-specification-data.pdf
70 | */
71 |
72 | const float a = (_exp2f(18.0f) - 16.0f)/117.45f;
73 | const float b = (1023.0f - 95.0f)/1023.0f;
74 | const float c = 95.0f/1023.0f;
75 | const float s = (7.0f*_logf(2.0f)*_exp2f(7.0f - 14.0f*c/b))/(a*b);
76 | const float t = (_exp2f(14.0f*(-c/b) + 6.0f) - 64.0f)/a;
77 |
78 | if (inv == 1) {
79 | return x < t ? x*s + t : (_exp2f(14.0f*(x - c)/b + 6.0f) - 64.0f)/a;
80 | } else {
81 | return x < t ? (x - t)/s : (_log2f(a*x + 64.0f) - 6.0f)/14.0f*b + c;
82 | }
83 | }
84 |
85 | __DEVICE__ float oetf_blackmagic_filmgen5(float x, int inv) {
86 | /* Blackmagic Film Generation 5
87 | Specified in the Blackmagic Generation 5 Color Science whitepaper included in the Blackmagic Raw SDK available here
88 | https://www.blackmagicdesign.com/support/download/1bad3dc74c2c4a908ce5c9ce8b9f74f8/Linux
89 | At this path in the installer:
90 | /usr/lib64/blackmagic/BlackmagicRAWSDK/Documents/Blackmagic Generation 5 Color Science Technical Reference.pdf
91 | */
92 |
93 | const float A = 0.08692876065491224f;
94 | const float B = 0.005494072432257808f;
95 | const float C = 0.5300133392291939f;
96 | const float D = 8.283605932402494f;
97 | const float E = 0.09246575342465753f;
98 | const float LIN_CUT = 0.005f;
99 | const float LOG_CUT = D * LIN_CUT + E;
100 |
101 | if (inv == 1) {
102 | return x < LOG_CUT ? (x - E)/D : _expf((x - C)/A) - B;
103 | } else {
104 | return x < LIN_CUT ? D*x + E : A*_logf(x + B) + C;
105 | }
106 | }
107 |
108 | __DEVICE__ float oetf_canon_clog2(float x, int inv) {
109 | /* Canon CLog2
110 | CLog2 is intended for grading workflows, whereas CLog3 is intended for a more "direct to display" workflow.
111 |
112 | Canon log transfer functions are all described in this whitepaper:
113 | https://downloads.canon.com/nw/learn/white-papers/cinema-eos/white-paper-canon-log-gamma-curves.pdf
114 |
115 | The log transfer functions described above match the 1D LUTs available in the "Canon lookup table Version 201911"
116 | download available here
117 | https://www.usa.canon.com/internet/portal/us/home/support/details/cameras/cinema-eos/cinema-eos-c500-mark-ii?tab=drivers_downloads
118 |
119 | However in the CTL ACES IDT provided in the "Input Transform Version 202007 for EOS C500 Mark II" file
120 | at the above url, they add the /=0.9 on the scene-linear values. This function matches the IDT.
121 | */
122 | const float c0 = 0.092864125f;
123 | const float c1 = 0.24136077f;
124 | const float c2 = 87.099375f;
125 |
126 | if (inv == 1) {
127 | x = x < c0 ? -(_exp10f((c0 - x)/c1) - 1.0f)/c2 : (_exp10f((x - c0)/c1) - 1.0f)/c2;
128 | return x*0.9f;
129 | } else {
130 | x /= 0.9f;
131 | return x < 0.0f ? -c1*_log10f(1.0f - c2*x) + c0 : c1*_log10f(c2*x + 1.0f) + c0;
132 | }
133 | }
134 |
135 | __DEVICE__ float oetf_canon_clog3(float x, int inv) {
136 | /* Canon CLog3
137 | Warning: CLog3 is intended for a more "direct to display" workflow
138 | */
139 | const float sp0 = 0.014f;
140 | const float sp1 = 0.09746547f;
141 | const float sp2 = 0.15277891f;
142 | const float c0 = 0.36726845f;
143 | const float c1 = 14.98325f;
144 | const float c2 = 0.12783901f;
145 | const float c3 = 1.9754798f;
146 | const float c4 = 0.12512219f;
147 | const float c5 = 0.12240537f;
148 |
149 | if (inv == 1) {
150 | x = x < sp1 ? -(_exp10f((c2 - x)/c0) - 1.0f)/c1 : x <= sp2 ? (x - c4)/c3 : (_exp10f((x - c5)/c0) - 1.0f)/c1;
151 | return x*0.9f;
152 | } else {
153 | x /= 0.9f;
154 | return x < -sp0 ? -c0*_log10f(1.0f - c1*x) + c2 : x <= sp0 ? c3*x + c4 : c0*_log10f(c1*x + 1.0f) + c5;
155 | }
156 | }
157 |
158 | __DEVICE__ float oetf_dji_dlog(float x, int inv) {
159 | /* DJI D-Log
160 | https://dl.djicdn.com/downloads/zenmuse+x7/20171010/D-Log_D-Gamut_Whitepaper.pdf
161 | */
162 |
163 | if (inv == 1) {
164 | return x <= 0.14f ? (x - 0.0929f)/6.025f : (_exp10f((3.89616f*x - 2.27752f)) - 0.0108f)/0.9892f;
165 | } else {
166 | return x <= 0.0078f ? 6.025f*x + 0.0929f : (_log10f(x*0.9892f + 0.0108f))*0.256663f + 0.584555f;
167 | }
168 | }
169 |
170 | __DEVICE__ float oetf_fujifilm_flog(float x, int inv) {
171 | /* Fujifilm F-Log
172 | https://dl.fujifilm-x.com/support/lut/F-Log_DataSheet_E_Ver.1.0.pdf
173 | */
174 | const float a = 0.555556f;
175 | const float b = 0.009468f;
176 | const float c = 0.344676f;
177 | const float d = 0.790453f;
178 | const float e = 8.735631f;
179 | const float f = 0.092864f;
180 | const float cut1 = 0.00089f;
181 | const float cut2 = 0.1005377752f;
182 |
183 | if (inv == 1) {
184 | return x < cut2 ? (x-f)/e : (_exp10f(((x - d)/c))/a - b/a);
185 | } else {
186 | return x < cut1 ? e*x+f : c*_log10f(a*x + b) + d;
187 | }
188 | }
189 |
190 | __DEVICE__ float oetf_fujifilm_flog2(float x, int inv) {
191 | /* Fujifilm F-Log2
192 | https://dl.fujifilm-x.com/support/lut/F-Log2_DataSheet_E_Ver.1.0.pdf
193 | */
194 | const float a = 5.555556f;
195 | const float b = 0.064829f;
196 | const float c = 0.245281f;
197 | const float d = 0.384316f;
198 | const float e = 8.799461f;
199 | const float f = 0.092864f;
200 | const float cut1 = 0.000889f;
201 | const float cut2 = 0.100686685370811f;
202 |
203 | if (inv == 1) {
204 | return x < cut2 ? (x-f)/e : (_exp10f(((x - d)/c))/a - b/a);
205 | } else {
206 | return x < cut1 ? e*x+f : c*_log10f(a*x + b) + d;
207 | }
208 | }
209 |
210 | __DEVICE__ float oetf_gopro_protune(float x, int inv) {
211 | /* GoPro Protune Flat log curve
212 | Unable to find whitepaper on this but it is described in this file from the original HPD opencolorio ACES config:
213 | https://github.com/hpd/OpenColorIO-Configs/blob/master/aces_1.0.3/python/aces_ocio/colorspaces/gopro.py
214 | */
215 | if (inv == 1) {
216 | return (_powf(113.0f, x) - 1.0f)/112.0f;
217 | } else {
218 | return _logf(x*112.0f + 1.0f)/_logf(113.0f);
219 | }
220 | }
221 |
222 | __DEVICE__ float oetf_leica_llog(float x, int inv) {
223 | /* Leica L-Log
224 | https://leica-camera.com/sites/default/files/pm-65977-210914__L-Log_Reference_Manual_EN.pdf
225 | */
226 | const float a = 8.0f;
227 | const float b = 0.09f;
228 | const float c = 0.27f;
229 | const float d = 1.3f;
230 | const float e = 0.0115f;
231 | const float f = 0.6f;
232 | const float c0 = 0.006f;
233 | const float c1 = 0.138f;
234 |
235 | if (inv == 1) {
236 | return x < c1 ? (x - b)/a : (_exp10f((x - f)/c) - e)/d;
237 | } else {
238 | return x < c0 ? a*x + b : c*_log10f(d*x + e) + f;
239 | }
240 | }
241 |
242 | __DEVICE__ float oetf_nikon_nlog(float x, int inv) {
243 | /* Nikon N-Log
244 | http://download.nikonimglib.com/archive3/hDCmK00m9JDI03RPruD74xpoU905/N-Log_Specification_(En)01.pdf
245 | */
246 | const float a = 619.0f/1023.0f;
247 | const float b = 150.0f/1023.0f;
248 | const float c = 650.0f/1023.0f;
249 | const float d = 0.0075f;
250 | const float c0 = 452.0f/1023.0f;
251 | const float c1 = 0.328f;
252 |
253 | if (inv == 1) {
254 | return x > c0 ? _expf((x - a)/b) : _powf(x/c, 3.0f) - d;
255 | } else {
256 | return x > c1 ? b*_logf(x) + a : c*_powf(x + d, 1.0f/3.0f);
257 | }
258 | }
259 |
260 | __DEVICE__ float oetf_panasonic_vlog(float x, int inv) {
261 | /* Panasonic V-Log
262 | https://pro-av.panasonic.net/en/cinema_camera_varicam_eva/support/pdf/VARICAM_V-Log_V-Gamut.pdf
263 | */
264 | const float cut1 = 0.01f;
265 | const float cut2 = 0.181f;
266 | const float b = 0.00873f;
267 | const float c = 0.241514f;
268 | const float d = 0.598206f;
269 |
270 | if (inv == 1) {
271 | return x < cut2 ? (x - 0.125f)/5.6f : _exp10f((x - d)/c) - b;
272 | } else {
273 | return x < cut1 ? 5.6f*x + 0.125f : c*_log10f(x + b) + d;
274 | }
275 | }
276 |
277 | __DEVICE__ float oetf_red_log3g10(float x, int inv) {
278 | /* Red Log3G10
279 | https://docs.red.com/955-0187/PDF/915-0187%20Rev-C%20%20%20RED%20OPS,%20White%20Paper%20on%20REDWideGamutRGB%20and%20Log3G10.pdf
280 | */
281 | const float a = 0.224282f;
282 | const float b = 155.975327f;
283 | const float c = 0.01f;
284 | const float g = 15.1927f;
285 |
286 | if (inv == 1) {
287 | return x < 0.0f ? (x/g) - c : (_exp10f(x/a) - 1.0f)/b - c;
288 | } else {
289 | return x < -c ? (x + c)*g : a*_log10f((x + c)*b + 1.0f);
290 | }
291 | }
292 |
293 | __DEVICE__ float oetf_sony_slog2(float x, int inv) {
294 | /* Sony S-Log2
295 | from the pdf originally retrieved from :
296 | https://pro.sony/ue_US/?sonyref=pro.sony.com/bbsccms/assets/files/micro/dmpc/training/S-Log2_Technical_PaperV1_0.pdf
297 | Link is down, here is a mirror:
298 | https://mega.nz/file/e6hDxC5b#YaRzePfGFFPkx_hRtmqw2gTT0NIPuzlJycwCP38H720
299 | */
300 | const float c0 = 0.432699f;
301 | const float c1 = 155.0f;
302 | const float c2 = 219.0f;
303 | const float c3 = 0.037584f;
304 | const float c4 = 0.616596f;
305 | const float c5 = 0.03f;
306 | const float c6 = 3.53881278538813f;
307 | const float c7 = 0.030001222851889303f;
308 |
309 | if (inv == 1) {
310 | x = (x - 64.0f/1023.0f)/(876.0f/1023.0f);
311 | x = x < c7 ? (x - c7)/c6 : c2*(_exp10f((x - c4 - c5)/c0) - c3)/c1;
312 | return x*0.9f;
313 | } else {
314 | x /= 0.9f;
315 | x = x < 0.0f ? x*c6 + c7 : (c0*_log10f(c1*x/c2 + c3) + c4) + c5;
316 | return x*(876.0f/1023.0f) + 64.0f/1023.0f;
317 | }
318 | }
319 |
320 | __DEVICE__ float oetf_sony_slog3(float x, int inv) {
321 | /* Sony S-Log3
322 | https://pro.sony/s3/cms-static-content/uploadfile/06/1237494271406.pdf
323 | */
324 | const float a = 0.01125f;
325 | const float b = 420.0f;
326 | const float c = 261.5f;
327 | const float d = 171.2102946929f;
328 | const float e = 95.0f;
329 | const float f = 0.18f;
330 | const float o = 0.01f;
331 |
332 | if (inv == 1) {
333 | return x < d/1023.0f ? (x*1023.0f - e)*a/(d-e) : (_exp10f(((x*1023.0f - b)/c))*(f + o) - o);
334 | } else {
335 | return x < a ? (x*(d - e)/a + e)/1023.0f : (b + _log10f((x + o)/(f + o))*c)/1023.0f;
336 | }
337 | }
338 |
339 | __DEVICE__ float oetf_davinci_intermediate(float x, int inv) {
340 | /* DaVinci Intermediate Log
341 | https://documents.blackmagicdesign.com/InformationNotes/DaVinci_Resolve_17_Wide_Gamut_Intermediate.pdf
342 | */
343 |
344 | const float A = 0.0075f;
345 | const float B = 7.0f;
346 | const float C = 0.07329248f;
347 | const float M = 10.44426855f;
348 | const float LIN_CUT = 0.00262409f;
349 | const float LOG_CUT = 0.02740668f;
350 |
351 | if (inv == 1) {
352 | return x <= LOG_CUT ? x/M : _exp2f(x/C - B) - A;
353 | } else {
354 | return x <= LIN_CUT ? x*M : (_log2f(x + A) + B)*C;
355 | }
356 | }
357 |
358 | __DEVICE__ float oetf_filmlight_tlog(float x, int inv) {
359 | /* Filmlight T-Log
360 | Specified in the flspace file included with the Baselight software
361 | /etc/colourspaces/FilmLight_TLog_EGamut.flspace
362 | */
363 |
364 | const float o = 0.075f;
365 | const float A = 0.5520126568606655f;
366 | const float B = 0.09232902596577353f;
367 | const float C = 0.0057048244042473785f;
368 | const float G = 16.184376489665897f;
369 |
370 | if (inv == 1) {
371 | return x < o ? (x-o)/G : _expf((x - A)/B) - C;
372 | } else {
373 | return x < 0.0f ? G*x + o : _logf(x + C)*B + A;
374 | }
375 | }
376 |
377 | __DEVICE__ float oetf_kodak_cineon(float x, int inv) {
378 | /* Kodak Cineon Log
379 | https://github.com/imageworks/OpenColorIO-Configs/blob/master/nuke-default/make.py
380 | */
381 | const float a = 685.0f;
382 | const float b = 300.0f;
383 | const float c = 95.0f;
384 | const float off = _exp10f((c - a)/b);
385 |
386 | if (inv == 1) {
387 | return (_exp10f(((1023.0f*x - a)/b)) - off)/(1.0f - off);
388 | } else {
389 | return (a + b*_log10f(x*(1.0f - off) + off))/1023.0f;
390 | }
391 | }
392 |
393 | // __DEVICE__ float oetf_(float x, int inv) {
394 | // /*
395 | //
396 | // */
397 | // if (inv == 1) {
398 | // return x;
399 | // } else {
400 | // return x;
401 | // }
402 | // }
403 |
404 | __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
405 | {
406 |
407 | float3 rgb = make_float3(p_R, p_G, p_B);
408 |
409 | if (curve == acescc) {
410 | rgb.x = oetf_acescc(rgb.x, invert);
411 | rgb.y = oetf_acescc(rgb.y, invert);
412 | rgb.z = oetf_acescc(rgb.z, invert);
413 | } else if (curve == acescct) {
414 | rgb.x = oetf_acescct(rgb.x, invert);
415 | rgb.y = oetf_acescct(rgb.y, invert);
416 | rgb.z = oetf_acescct(rgb.z, invert);
417 | } else if (curve == arri_logc3) {
418 | rgb.x = oetf_arri_logc3(rgb.x, invert);
419 | rgb.y = oetf_arri_logc3(rgb.y, invert);
420 | rgb.z = oetf_arri_logc3(rgb.z, invert);
421 | } else if (curve == arri_logc4) {
422 | rgb.x = oetf_arri_logc4(rgb.x, invert);
423 | rgb.y = oetf_arri_logc4(rgb.y, invert);
424 | rgb.z = oetf_arri_logc4(rgb.z, invert);
425 | } else if (curve == blackmagic_filmgen5) {
426 | rgb.x = oetf_blackmagic_filmgen5(rgb.x, invert);
427 | rgb.y = oetf_blackmagic_filmgen5(rgb.y, invert);
428 | rgb.z = oetf_blackmagic_filmgen5(rgb.z, invert);
429 | } else if (curve == canon_clog2) {
430 | rgb.x = oetf_canon_clog2(rgb.x, invert);
431 | rgb.y = oetf_canon_clog2(rgb.y, invert);
432 | rgb.z = oetf_canon_clog2(rgb.z, invert);
433 | } else if (curve == canon_clog3) {
434 | rgb.x = oetf_canon_clog3(rgb.x, invert);
435 | rgb.y = oetf_canon_clog3(rgb.y, invert);
436 | rgb.z = oetf_canon_clog3(rgb.z, invert);
437 | } else if (curve == dji_dlog) {
438 | rgb.x = oetf_dji_dlog(rgb.x, invert);
439 | rgb.y = oetf_dji_dlog(rgb.y, invert);
440 | rgb.z = oetf_dji_dlog(rgb.z, invert);
441 | } else if (curve == fujifilm_flog) {
442 | rgb.x = oetf_fujifilm_flog(rgb.x, invert);
443 | rgb.y = oetf_fujifilm_flog(rgb.y, invert);
444 | rgb.z = oetf_fujifilm_flog(rgb.z, invert);
445 | } else if (curve == fujifilm_flog2) {
446 | rgb.x = oetf_fujifilm_flog2(rgb.x, invert);
447 | rgb.y = oetf_fujifilm_flog2(rgb.y, invert);
448 | rgb.z = oetf_fujifilm_flog2(rgb.z, invert);
449 | } else if (curve == gopro_protune) {
450 | rgb.x = oetf_gopro_protune(rgb.x, invert);
451 | rgb.y = oetf_gopro_protune(rgb.y, invert);
452 | rgb.z = oetf_gopro_protune(rgb.z, invert);
453 | } else if (curve == leica_llog) {
454 | rgb.x = oetf_leica_llog(rgb.x, invert);
455 | rgb.y = oetf_leica_llog(rgb.y, invert);
456 | rgb.z = oetf_leica_llog(rgb.z, invert);
457 | } else if (curve == nikon_nlog) {
458 | rgb.x = oetf_nikon_nlog(rgb.x, invert);
459 | rgb.y = oetf_nikon_nlog(rgb.y, invert);
460 | rgb.z = oetf_nikon_nlog(rgb.z, invert);
461 | } else if (curve == panasonic_vlog) {
462 | rgb.x = oetf_panasonic_vlog(rgb.x, invert);
463 | rgb.y = oetf_panasonic_vlog(rgb.y, invert);
464 | rgb.z = oetf_panasonic_vlog(rgb.z, invert);
465 | } else if (curve == red_log3g10) {
466 | rgb.x = oetf_red_log3g10(rgb.x, invert);
467 | rgb.y = oetf_red_log3g10(rgb.y, invert);
468 | rgb.z = oetf_red_log3g10(rgb.z, invert);
469 | } else if (curve == sony_slog2) {
470 | rgb.x = oetf_sony_slog2(rgb.x, invert);
471 | rgb.y = oetf_sony_slog2(rgb.y, invert);
472 | rgb.z = oetf_sony_slog2(rgb.z, invert);
473 | } else if (curve == sony_slog3) {
474 | rgb.x = oetf_sony_slog3(rgb.x, invert);
475 | rgb.y = oetf_sony_slog3(rgb.y, invert);
476 | rgb.z = oetf_sony_slog3(rgb.z, invert);
477 | } else if (curve == davinci_intermediate) {
478 | rgb.x = oetf_davinci_intermediate(rgb.x, invert);
479 | rgb.y = oetf_davinci_intermediate(rgb.y, invert);
480 | rgb.z = oetf_davinci_intermediate(rgb.z, invert);
481 | } else if (curve == filmlight_tlog) {
482 | rgb.x = oetf_filmlight_tlog(rgb.x, invert);
483 | rgb.y = oetf_filmlight_tlog(rgb.y, invert);
484 | rgb.z = oetf_filmlight_tlog(rgb.z, invert);
485 | } else if (curve == kodak_cineon) {
486 | rgb.x = oetf_kodak_cineon(rgb.x, invert);
487 | rgb.y = oetf_kodak_cineon(rgb.y, invert);
488 | rgb.z = oetf_kodak_cineon(rgb.z, invert);
489 | }
490 |
491 | return rgb;
492 |
493 | }
--------------------------------------------------------------------------------
/utilities/README.md:
--------------------------------------------------------------------------------
1 | # Utilities
2 | Here are a couple of utility DCTLs for doing basic operations in Resolve.
3 |
4 | ## GamutConvert
5 | Converts from one gamut to another. Calculates a 3x3 Matrix at machine precision, does not rely on pre-defined matrices.
6 |
7 | ## LogConvert
8 | Convert from to or from a log encoding. Implemented directly in code (no luts), so good precision. Includes links to the original source whitepapers where possible.
--------------------------------------------------------------------------------