Skip to content

Commit 2f495a2

Browse files
author
Jed Smith
committed
separate threshold parameters by component for dctl fuse and matchbox versions of the tool.
1 parent ffae7da commit 2f495a2

File tree

4 files changed

+183
-79
lines changed

4 files changed

+183
-79
lines changed

GamutCompress.dctl

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
DEFINE_UI_PARAMS(cmethod, method, DCTLUI_COMBO_BOX, 2, {L, R, P, E, A, T}, {log, reinhard, power, exp, arctan, tanh});
2-
DEFINE_UI_PARAMS(threshold, threshold, DCTLUI_SLIDER_FLOAT, 0.2f, 0.0f, 0.6f, 0.0f);
1+
DEFINE_UI_PARAMS(threshold_r, threshold r, DCTLUI_SLIDER_FLOAT, 0.2f, 0.0f, 0.6f, 0.0f);
2+
DEFINE_UI_PARAMS(threshold_g, threshold g, DCTLUI_SLIDER_FLOAT, 0.2f, 0.0f, 0.6f, 0.0f);
3+
DEFINE_UI_PARAMS(threshold_b, threshold b, DCTLUI_SLIDER_FLOAT, 0.2f, 0.0f, 0.6f, 0.0f);
34
DEFINE_UI_PARAMS(power, power, DCTLUI_SLIDER_FLOAT, 1.2f, 1.0f, 3.0f, 1.0f);
45
DEFINE_UI_PARAMS(shd_rolloff, shd rolloff, DCTLUI_SLIDER_FLOAT, 0.03f, 0.0f, 0.1f, 0.0f);
56
DEFINE_UI_PARAMS(cyan, cyan, DCTLUI_SLIDER_FLOAT, 0.09f, 0.0f, 1.0f, 0.0f);
67
DEFINE_UI_PARAMS(magenta, magenta, DCTLUI_SLIDER_FLOAT, 0.24f, 0.0f, 1.0f, 0.0f);
78
DEFINE_UI_PARAMS(yellow, yellow, DCTLUI_SLIDER_FLOAT, 0.12f, 0.0f, 1.0f, 0.0f);
8-
DEFINE_UI_PARAMS(compress_secondaries, compress secondaries, DCTLUI_CHECK_BOX, 0);
9+
DEFINE_UI_PARAMS(cmethod, method, DCTLUI_COMBO_BOX, 2, {L, R, P, E, A, T}, {log, reinhard, power, exp, arctan, tanh});
910
DEFINE_UI_PARAMS(working_colorspace, working space, DCTLUI_COMBO_BOX, 0, {acescct, acescc, acescg}, {acescct, acescc, acescg});
11+
DEFINE_UI_PARAMS(hexagonal, hexagonal, DCTLUI_CHECK_BOX, 0);
1012
DEFINE_UI_PARAMS(invert, invert, DCTLUI_CHECK_BOX, 0);
1113

1214
__CONSTANT__ float pi = 3.14159265359f;
@@ -221,7 +223,10 @@ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p
221223
}
222224

223225
// thr is the percentage of the core gamut to protect: the complement of threshold.
224-
float thr = 1.0f - threshold;
226+
float3 thr = make_float3(
227+
1.0f-_fmaxf(0.00001, threshold_r),
228+
1.0f-_fmaxf(0.00001, threshold_g),
229+
1.0f-_fmaxf(0.00001, threshold_b));
225230

226231
// lim is the max distance from the gamut boundary that will be compressed
227232
// 0 is a no-op, 1 will compress colors from a distance of 2.0 from achromatic to the gamut boundary
@@ -236,9 +241,9 @@ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p
236241
// Not sure of a way to pre-calculate a constant using the values from the ui parameters in Resolve DCTL...
237242
// This approach might have performance implications
238243
lim = make_float3(
239-
bisect(_fmaxf(0.0001f, cyan)+1.0f, thr, method),
240-
bisect(_fmaxf(0.0001f, magenta)+1.0f, thr, method),
241-
bisect(_fmaxf(0.0001f, yellow)+1.0f, thr, method));
244+
bisect(_fmaxf(0.0001f, cyan)+1.0f, thr.x, method),
245+
bisect(_fmaxf(0.0001f, magenta)+1.0f, thr.y, method),
246+
bisect(_fmaxf(0.0001f, yellow)+1.0f, thr.z, method));
242247
}
243248

244249
// achromatic axis
@@ -256,23 +261,23 @@ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p
256261
// compress distance with user controlled parameterized shaper function
257262
float sat;
258263
float3 csat, cdist;
259-
if (compress_secondaries) {
264+
if (hexagonal) {
260265
// Based on Nick Shaw's variation on the gamut mapping algorithm
261266
// https://community.acescentral.com/t/a-variation-on-jeds-rgb-gamut-mapper/3060
262267
sat = _fmaxf(dist.x, _fmaxf(dist.y, dist.z));
263268
csat = make_float3(
264-
compress(sat, lim.x, thr, invert, method, power),
265-
compress(sat, lim.y, thr, invert, method, power),
266-
compress(sat, lim.z, thr, invert, method, power));
269+
compress(sat, lim.x, thr.x, invert, method, power),
270+
compress(sat, lim.y, thr.y, invert, method, power),
271+
compress(sat, lim.z, thr.z, invert, method, power));
267272
cdist = sat == 0.0f ? dist : make_float3(
268273
dist.x * csat.x / sat,
269274
dist.y * csat.y / sat,
270275
dist.z * csat.z / sat);
271276
} else {
272277
cdist = make_float3(
273-
compress(dist.x, lim.x, thr, invert, method, power),
274-
compress(dist.y, lim.y, thr, invert, method, power),
275-
compress(dist.z, lim.z, thr, invert, method, power));
278+
compress(dist.x, lim.x, thr.x, invert, method, power),
279+
compress(dist.y, lim.y, thr.y, invert, method, power),
280+
compress(dist.z, lim.z, thr.z, invert, method, power));
276281
}
277282

278283
// recalculate rgb from compressed distance and achromatic
@@ -282,10 +287,6 @@ __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p
282287
ach-cdist.y*ach_shd,
283288
ach-cdist.z*ach_shd);
284289

285-
crgb.x = isnan(crgb.x) ? 0.0f : crgb.x;
286-
crgb.y = isnan(crgb.y) ? 0.0f : crgb.y;
287-
crgb.z = isnan(crgb.z) ? 0.0f : crgb.z;
288-
289290
if (working_colorspace == acescct) {
290291
crgb.x = lin_to_acescct(crgb.x);
291292
crgb.y = lin_to_acescct(crgb.y);
Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,35 @@ function Create()
9898
{CCS_AddString = "tanh", },
9999
})
100100

101-
InThreshold = self:AddInput("threshold", "threshold", {
101+
InHexagonal = self:AddInput("hexagonal", "hexagonal", {
102+
LINKID_DataType = "Number",
103+
INPID_InputControl = "CheckboxControl",
104+
INP_MinAllowed = 0.0,
105+
INP_MaxAllowed = 1.0,
106+
INP_Default = 0.0,
107+
})
108+
109+
InThresholdR = self:AddInput("threshold_r", "threshold_r", {
102110
LINKID_DataType = "Number",
103111
INPID_InputControl = "SliderControl",
104112
INP_Default = 0.2,
105-
INP_MinAllowed = 0.0,
113+
INP_MinAllowed = 0.0001,
114+
INP_MaxScale = 0.6,
115+
})
116+
117+
InThresholdG = self:AddInput("threshold_g", "threshold_g", {
118+
LINKID_DataType = "Number",
119+
INPID_InputControl = "SliderControl",
120+
INP_Default = 0.2,
121+
INP_MinAllowed = 0.0001,
122+
INP_MaxScale = 0.6,
123+
})
124+
125+
InThresholdB = self:AddInput("threshold_b", "threshold_b", {
126+
LINKID_DataType = "Number",
127+
INPID_InputControl = "SliderControl",
128+
INP_Default = 0.2,
129+
INP_MinAllowed = 0.0001,
106130
INP_MaxScale = 0.6,
107131
})
108132

@@ -149,14 +173,6 @@ function Create()
149173
})
150174

151175
self:EndControlNest()
152-
153-
InHexagonal = self:AddInput("hexagonal", "hexagonal", {
154-
LINKID_DataType = "Number",
155-
INPID_InputControl = "CheckboxControl",
156-
INP_MinAllowed = 0.0,
157-
INP_MaxAllowed = 1.0,
158-
INP_Default = 0.0,
159-
})
160176

161177
InInvert = self:AddInput("invert", "invert", {
162178
LINKID_DataType = "Number",
@@ -187,13 +203,15 @@ function Process(req)
187203
local params = node:GetParamBlock(SolidParams)
188204

189205
params.method = InMethod:GetValue(req).Value
206+
params.hexagonal = InHexagonal:GetValue(req).Value
207+
params.threshold_r = InThresholdR:GetValue(req).Value
208+
params.threshold_g = InThresholdG:GetValue(req).Value
209+
params.threshold_b = InThresholdB:GetValue(req).Value
190210
params.power = InPower:GetValue(req).Value
191-
params.threshold = InThreshold:GetValue(req).Value
192211
params.shd_rolloff = InShdRolloff:GetValue(req).Value
193212
params.cyan = InCyan:GetValue(req).Value
194213
params.magenta = InMagenta:GetValue(req).Value
195214
params.yellow = InYellow:GetValue(req).Value
196-
params.hexagonal = InHexagonal:GetValue(req).Value
197215
params.invert = InInvert:GetValue(req).Value
198216
params.srcCompOrder = src:IsMask() and 1 or 15
199217

@@ -216,13 +234,15 @@ end
216234

217235
SolidParams = [[
218236
int method;
219-
float threshold;
237+
int hexagonal;
238+
float threshold_r;
239+
float threshold_g;
240+
float threshold_b;
220241
float power;
221242
float shd_rolloff;
222243
float cyan;
223244
float magenta;
224245
float yellow;
225-
int hexagonal;
226246
int invert;
227247
int srcCompOrder;
228248
]]
@@ -389,7 +409,10 @@ SolidKernel = [[
389409
}
390410

391411
// thr is the percentage of the core gamut to protect: the complement of threshold.
392-
float thr = 1.0f - params->threshold;
412+
float3 thr = make_float3(
413+
1.0f-_fmaxf(0.0001f, params->threshold_r),
414+
1.0f-_fmaxf(0.0001f, params->threshold_g),
415+
1.0f-_fmaxf(0.0001f, params->threshold_b));
393416

394417
// lim is the max distance from the gamut boundary that will be compressed
395418
// 0 is a no-op, 1 will compress colors from a distance of 2.0 from achromatic to the gamut boundary
@@ -404,9 +427,9 @@ SolidKernel = [[
404427
// Not sure of a way to pre-calculate a constant using the values from the ui parameters in Resolve DCTL...
405428
// This approach might have performance implications
406429
lim = make_float3(
407-
bisect(_fmaxf(0.0001f, params->cyan)+1.0f, thr, method),
408-
bisect(_fmaxf(0.0001f, params->magenta)+1.0f, thr, method),
409-
bisect(_fmaxf(0.0001f, params->yellow)+1.0f, thr, method));
430+
bisect(_fmaxf(0.0001f, params->cyan)+1.0f, thr.x, method),
431+
bisect(_fmaxf(0.0001f, params->magenta)+1.0f, thr.y, method),
432+
bisect(_fmaxf(0.0001f, params->yellow)+1.0f, thr.z, method));
410433
}
411434

412435
// achromatic axis
@@ -429,18 +452,18 @@ SolidKernel = [[
429452
// https://community.acescentral.com/t/a-variation-on-jeds-rgb-gamut-mapper/3060
430453
sat = _fmaxf(dist.x, _fmaxf(dist.y, dist.z));
431454
csat = make_float3(
432-
compress(sat, lim.x, thr, params->invert, method, params->power),
433-
compress(sat, lim.y, thr, params->invert, method, params->power),
434-
compress(sat, lim.z, thr, params->invert, method, params->power));
455+
compress(sat, lim.x, thr.x, params->invert, method, params->power),
456+
compress(sat, lim.y, thr.y, params->invert, method, params->power),
457+
compress(sat, lim.z, thr.z, params->invert, method, params->power));
435458
cdist = sat == 0 ? dist : make_float3(
436459
dist.x * csat.x / sat,
437460
dist.y * csat.y / sat,
438461
dist.z * csat.z / sat);
439462
} else {
440463
cdist = make_float3(
441-
compress(dist.x, lim.x, thr, params->invert, method, params->power),
442-
compress(dist.y, lim.y, thr, params->invert, method, params->power),
443-
compress(dist.z, lim.z, thr, params->invert, method, params->power));
464+
compress(dist.x, lim.x, thr.x, params->invert, method, params->power),
465+
compress(dist.y, lim.y, thr.y, params->invert, method, params->power),
466+
compress(dist.z, lim.z, thr.z, params->invert, method, params->power));
444467
}
445468

446469
// recalculate rgb from compressed distance and achromatic

GamutCompress.glsl

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
uniform sampler2D frontTex, matteTex, selectiveTex;
2-
uniform float threshold, power, cyan, magenta, yellow, shd_rolloff, adsk_result_w, adsk_result_h;
2+
uniform float power, cyan, magenta, yellow, shd_rolloff, adsk_result_w, adsk_result_h;
33
uniform int method, working_colorspace;
44
uniform bool invert, hexagonal;
5+
uniform vec3 threshold;
56

67
const float pi = 3.14159265359;
78

@@ -209,7 +210,10 @@ void main() {
209210
}
210211

211212
// thr is the percentage of the core gamut to protect: the complement of threshold.
212-
float thr = 1.0 - threshold;
213+
vec3 thr = vec3(
214+
1.0-max(0.00001, threshold.x),
215+
1.0-max(0.00001, threshold.y),
216+
1.0-max(0.00001, threshold.z));
213217

214218
// lim is the max distance from the gamut boundary that will be compressed
215219
// 0 is a no-op, 1 will compress colors from a distance of 2.0 from achromatic to the gamut boundary
@@ -224,9 +228,9 @@ void main() {
224228
// Not sure of a way to pre-calculate a constant using the values from the ui parameters in GLSL...
225229
// This approach might have performance implications
226230
lim = vec3(
227-
bisect(max(0.0001, cyan)+1.0, thr, method),
228-
bisect(max(0.0001, magenta)+1.0, thr, method),
229-
bisect(max(0.0001, yellow)+1.0, thr, method));
231+
bisect(max(0.0001, cyan)+1.0, thr.x, method),
232+
bisect(max(0.0001, magenta)+1.0, thr.y, method),
233+
bisect(max(0.0001, yellow)+1.0, thr.z, method));
230234
}
231235

232236
// achromatic axis
@@ -249,18 +253,18 @@ void main() {
249253
// https://community.acescentral.com/t/a-variation-on-jeds-rgb-gamut-mapper/3060
250254
sat = max(dist.x, max(dist.y, dist.z));
251255
csat = vec3(
252-
compress(sat, lim.x, thr, invert, method, power),
253-
compress(sat, lim.y, thr, invert, method, power),
254-
compress(sat, lim.z, thr, invert, method, power));
256+
compress(sat, lim.x, thr.x, invert, method, power),
257+
compress(sat, lim.y, thr.y, invert, method, power),
258+
compress(sat, lim.z, thr.z, invert, method, power));
255259
cdist = sat == 0.0 ? dist : vec3(
256260
dist.x * csat.x / sat,
257261
dist.y * csat.y / sat,
258262
dist.z * csat.z / sat);
259263
} else {
260264
cdist = vec3(
261-
compress(dist.x, lim.x, thr, invert, method, power),
262-
compress(dist.y, lim.y, thr, invert, method, power),
263-
compress(dist.z, lim.z, thr, invert, method, power));
265+
compress(dist.x, lim.x, thr.x, invert, method, power),
266+
compress(dist.y, lim.y, thr.y, invert, method, power),
267+
compress(dist.z, lim.z, thr.z, invert, method, power));
264268
}
265269

266270
// recalculate rgb from compressed distance and achromatic

0 commit comments

Comments
 (0)