Skip to content

Instantly share code, notes, and snippets.

@jedypod
Created June 7, 2020 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedypod/eb8fcb8a9d8ffdb3f414f7cdd9312a0e to your computer and use it in GitHub Desktop.
Save jedypod/eb8fcb8a9d8ffdb3f414f7cdd9312a0e to your computer and use it in GitHub Desktop.
set cut_paste_input [stack 0]
version 12.1 v2
Read {
inputs 0
file_type exr
file "../images/aces_gamut_vwg_image_submissions/Joseph Goldstone - arri_ludwigstraße_take0000_lens_wide_open.exr"
format "2880 1620 0 0 2880 1620 1 "
origset true
raw true
auto_alpha true
name Read27
tile_color 0x989898ff
note_font Helvetica
selected true
xpos 8650
ypos 8189
postage_stamp false
}
Group {
name Gamut1
label "\[if \{\[value invert]\} \{return \"\[value gamut_out] to \[value gamut_in]\"\} else \{return \"\[value gamut_in] to \[value gamut_out]\"\}]"
selected true
xpos 8650
ypos 8240
addUserKnob {20 GamutToXYZ_tab l GamutToXYZ}
addUserKnob {4 gamut_in l "gamut in" t "Choose source gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
addUserKnob {4 gamut_out l "gamut out" t "Choose destination gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_out ACEScg
addUserKnob {6 invert +STARTLINE}
}
Input {
inputs 0
name Input
xpos -40
ypos -130
}
Dot {
name Dot1
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -6
ypos -78
}
set Nce976fb0 [stack 0]
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name ColorMatrix2
label "RGB to XYZ"
xpos 180
ypos 32
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9872239828 -0.006113247015 0.01595330238}
{-0.007598329335 1.001861453 0.005330037326}
{0.00307257846 -0.00509596616 1.081680536}
}
invert {{!parent.ColorMatrix4.invert}}
name ColorMatrix1
label "CAT: Bradford\n ACES to D65"
note_font Helvetica
xpos 180
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name ColorMatrix3
label "XYZ to RGB"
xpos 180
ypos 176
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
push $Nce976fb0
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name RGBtoXYZ
xpos -260
ypos 38
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9874471426 -0.005980737507 0.01595583558}
{-0.00739388587 1.001675606 0.005319938064}
{0.003088310361 -0.005131930113 1.081959367}
}
invert {{"parent.RGBtoXYZ.wxy == 0.3127"}}
name ColorMatrix4
label "CAT: Bradford\n D60 to D65"
note_font Helvetica
xpos -260
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name XYZtoRGB
xpos -260
ypos 182
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
Switch {
inputs 2
which {{parent.invert}}
name switch_direction
note_font Helvetica
xpos -40
ypos 303
}
Output {
name Output
xpos -40
ypos 374
}
push $Nce976fb0
ColorMatrix {
matrix {
{{curve 0.9525524378 0.6624541879 0.7053968906 0.4123907983 0.6369580626 0.5049495697 0.4865709841 0.6380076408 0.7352752686 0.5022571683 0.7160496712 0.7064827085 0.5990839601 0.6796444654 0.6481720209 0.6065810919 0.7165006995 0.7976718545} {curve 0 0.1340042055 0.1640413404 0.3575843275 0.1446169019 0.2646814585 0.2656676769 0.2147038579 0.06860940903 0.2929667532 0.1296834797 0.1288010478 0.2489254922 0.1522114277 0.1940581352 0.2203479856 0.1010205746 0.1351878047} {curve 9.367863095e-05 0.1561876982 0.08101774752 0.180480808 0.1688809693 0.1830150485 0.1982172877 0.09774444997 0.1465712637 0.1552320272 0.1047228053 0.1151721701 0.1024464965 0.1186000481 0.108225815 0.123526901 0.1467743814 0.03133957833}}
{{curve 0.3439664543 0.2722287476 0.2801307142 0.2126390189 0.2627002299 0.237623319 0.2289745659 0.2919537723 0.2866941094 0.1387997568 0.2612613738 0.2709796727 0.2150758505 0.2606855333 0.2830046713 0.2680045366 0.258728236 0.2880405784} {curve 0.7281661034 0.6740817428 0.8202066422 0.7151686549 0.6779980659 0.6891706586 0.6917385459 0.8238410354 0.8429791331 0.910841465 0.8696421385 0.786606431 0.8850684762 0.7748944759 0.8131960034 0.8326833844 0.7246823311 0.7118694782} {curve -0.07213255018 0.05368951708 -0.1003373638 0.07219231874 0.05930171534 0.07320601493 0.07928691059 -0.1157948226 -0.1296732277 -0.04964122549 -0.1309035122 -0.05758608505 -0.1001443192 -0.03558001295 -0.09620071948 -0.1006879359 0.01658944227 8.991353388e-05}}
{{curve -3.863927134e-08 -0.005574660841 -0.1037815213 0.01933082007 0 0 0 0.0027982709 -0.07968087494 0.07801423222 -0.009676366113 -0.009677864611 -0.03206583485 -0.009310216643 -0.01825834997 -0.02941203304 -2.906408625e-08 0} {curve 0 0.004060741514 -0.07290724665 0.1191947311 0.0280726999 0.0449459292 0.04511339962 -0.06703422964 -0.3473432064 -0.3148325086 -0.2364816219 0.004600019194 -0.02765839547 -0.004612449091 -0.08316776901 -0.08659287542 0.05121183768 -1.262213711e-08} {curve 1.008825183 1.010339141 1.265746474 0.950532198 1.060985088 0.9638792276 1.043944359 1.153293729 1.51608181 1.325875998 1.335215807 1.094135642 1.148782015 1.102980375 1.190483928 1.205062628 0.7738927603 0.8248898983}}
}
name mtx
label "\n"
xpos -40
ypos 38
addUserKnob {20 Params}
addUserKnob {12 rxy}
rxy {{curve 0.7347 0.713 0.8 0.64 0.708 0.68 0.68 0.684 0.780308 0.69848046 0.74 0.73 0.766 0.73 0.71 0.7177 0.7347 0.734699} {curve 0.2653 0.293 0.3177 0.33 0.292 0.32 0.32 0.313 0.304253 0.19302645 0.27 0.28 0.275 0.28 0.31 0.3171 0.2653 0.265301}}
addUserKnob {12 gxy}
gxy {{curve 0 0.165 0.18 0.3 0.17 0.265 0.265 0.221 0.121595 0.32955538 0.17 0.14 0.225 0.165 0.21 0.228 0.1152 0.159597} {curve 1 0.83 0.9 0.6 0.797 0.69 0.69 0.848 1.493994 1.02459662 1.14 0.855 0.8 0.84 0.88 0.8616 0.8264 0.840403}}
addUserKnob {12 bxy}
bxy {{curve 0.0001 0.128 0.065 0.15 0.131 0.15 0.15 0.0861 0.095612 0.10844263 0.08 0.1 0.089 0.1 0.09 0.1006 0.1566 0.036598} {curve -0.077 0.044 -0.0805 0.06 0.046 0.06 0.06 -0.102 -0.084589 -0.03467857 -0.1 -0.05 -0.087 -0.03 -0.08 -0.082 0.0177 0.000105}}
addUserKnob {12 wxy}
wxy {{curve 0.32168 0.32168 0.3127 0.3127 0.3127 0.32168 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3457 0.345704} {curve 0.33767 0.33767 0.329 0.329 0.329 0.33767 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.3585 0.35854}}
}
end_group
Crop {
box {1058.400024 240 1492.5 434}
reformat true
crop false
name Crop13
note_font Helvetica
selected true
xpos 8650
ypos 8319
}
Dot {
name Dot63
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 8684
ypos 8370
}
set N51f0100 [stack 0]
Group {
name VisualizeColorDistance19
selected true
xpos 8430
ypos 8366
addUserKnob {20 VisualizeColorDistance}
addUserKnob {4 type M {inside outside}}
type outside
addUserKnob {6 show_distance l "show distance" -STARTLINE}
addUserKnob {7 threshold t "threshold of color distance to visualize. 1.0 is the edge of the gamut boundary. 0.0 is all colors." R 0 1.2}
threshold 1
addUserKnob {7 shd_rolloff l "shd rolloff" R 0 0.1}
shd_rolloff 0.03
addUserKnob {4 bg t "choose bg to put behind result colors" M {checkerboard "solid color"}}
addUserKnob {41 color T Fill1.color}
}
Input {
inputs 0
name Input
xpos -40
ypos -285
}
Dot {
name Dot1
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -6
ypos -174
}
set Nd116ec90 [stack 0]
Dot {
name Dot2
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -116
ypos -174
}
set Nd701d9e0 [stack 0]
Dot {
name Dot5
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -226
ypos -174
}
set Ncff74be0 [stack 0]
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
note_font Helvetica
xpos -370
ypos -129
}
set Ncec72240 [stack 0]
push $Ncff74be0
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
note_font Helvetica
xpos -260
ypos -129
}
push $Ncec72240
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
note_font Helvetica
xpos -370
ypos -81
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
note_font Helvetica
xpos -260
ypos -81
}
set N1784a5c0 [stack 0]
Dot {
name Dot4
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -226
ypos 66
}
push $N1784a5c0
push $Nd701d9e0
MergeExpression {
inputs 2
temp_name0 limit
temp_expr0 threshold
temp_name1 sat
temp_expr1 max(Ar,Ag,Ab)
expr0 type?(sat>=limit?Br:0):sat<=limit?Br:0
expr1 type?(sat>=limit?Bg:0):sat<=limit?Bg:0
expr2 type?(sat>=limit?Bb:0):sat<=limit?Bb:0
expr3 type?(sat>limit?1:0):sat<limit?1:0
name MergeExpression1
note_font Helvetica
xpos -150
ypos -81
}
Dot {
name Dot3
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -116
ypos -30
}
push $Nd116ec90
Fill {
output rgb
color 0.18
name Fill1
note_font Helvetica
xpos -40
ypos -129
}
CheckerBoard2 {
inputs 0
color0 0.1000000015
color1 {{parent.color} {parent.color} {parent.color} {parent.color}}
color2 {{color0} {color0} {color0} {color0}}
color3 {{color1} {color1} {color1} {color1}}
linecolor 0
centerlinewidth 0
name CheckerBoard1
note_font Helvetica
xpos 70
ypos -129
postage_stamp false
}
Reformat {
type "to box"
box_width {{parent.input.width}}
box_height {{parent.input.height}}
box_fixed true
resize fill
name ReformatBox
xpos 70
ypos -82
}
Switch {
inputs 2
which {{parent.bg}}
name Switch1
note_font Helvetica
xpos -40
ypos -81
}
Merge2 {
inputs 2
bbox B
name Merge1
note_font Helvetica
xpos -40
ypos -33
}
Switch {
inputs 2
which {{parent.show_distance}}
name switch_distance
note_font Helvetica
xpos -40
ypos 63
}
Output {
name Output
xpos -40
ypos 110
}
end_group
Read {
inputs 0
file_type tiff
file "../images/aces_gamut_vwg_image_submissions/Joseph Goldstone - orig_arri_ludwigstraße_take0000_lens_wide_open_r709_d65_r1886.tif"
format "2880 1620 0 0 2880 1620 1 "
origset true
raw true
auto_alpha true
name Read28
tile_color 0x989898ff
note_font Helvetica
selected true
xpos 8870
ypos 8189
postage_stamp false
}
Crop {
box {1058.400024 240 1492.5 434}
reformat true
crop false
name Crop15
note_font Helvetica
selected true
xpos 8870
ypos 8319
}
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "arri r709_d65_r1886"
old_message {{97 114 114 105 32 114 55 48 57 95 100 54 53 95 114 49 56 56 54}
}
box {212.25 0.875 439.75 43.125}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 11 24 12 24 13 24 14 24 15 24 16 24 17 24 18 24 0 50}
}
cursor_position 11
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text5
note_font Helvetica
selected true
xpos 8870
ypos 8363
}
Dot {
name Dot70
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 8904
ypos 8730
}
push $N51f0100
Group {
name GamutCompress14
label "\[value method]: \[value direction]\nDefaults"
selected true
xpos 8760
ypos 8402
addUserKnob {20 GamutCompress}
addUserKnob {41 method T compress.method}
addUserKnob {22 reset t "Reset knobs to default values. Distance limits are calculated based on an the average of a selection of digital cinema cameras." -STARTLINE T "n = nuke.thisNode()\nnuke.root().begin()\ndefaults = \{\n 'threshold': 0.2,\n 'shd_rolloff': 0.03,\n 'cyan': 0.09,\n 'magenta':0.24,\n 'yellow': 0.12,\n\}\nfor k, v in defaults.items():\n n\[k].setValue(v)"}
addUserKnob {41 threshold t "Percentage of the outer gamut boundary to affect. A value of 0.2 means 20% of the outer gamut will be utilized for gamut compression." T compress.threshold}
addUserKnob {7 shd_rolloff l "shd rolloff" t "Shadow rolloff reduces the gamut compression effect below the specified pixel value. This reduces invertability issues with negative pixels in shadow grain." R 0 0.1}
shd_rolloff 0.03
addUserKnob {26 distance_limit_label l " " t "Specifies the distance beyond the gamut boundary to map to the gamut boundary for each color component." T "<b>distance limit"}
addUserKnob {41 cyan t "Maximum distance beyond the green-blue gamut boundary to compress to the gamut boundary." T compress.cyan}
addUserKnob {41 magenta t "Maximum distance beyond the blue-red gamut boundary to compress to the gamut boundary." T compress.magenta}
addUserKnob {41 yellow t "Maximum distance beyond the red-green gamut boundary to compress to the gamut boundary." T compress.yellow}
addUserKnob {26 ""}
addUserKnob {26 calculate_distance_limit_label l " " T "<b>calculate distance limit"}
addUserKnob {41 gamut t "The current gamut in which we are working." T Gamut.gamut_in}
addUserKnob {41 src_gamut l "source gamut" t "The source gamut from which this image was transformed." -STARTLINE T Gamut.gamut_out}
addUserKnob {22 calc_max_limit l "Calc Max Distance" t "Calculate the max distance given current gamut and source gamut." T "def get_max(ct_node, ch):\n max_knob = ct_node\['maxlumapixvalue']\n ct_node\['maxlumapixdata'].clearAnimated()\n ct_node\['minlumapixdata'].clearAnimated()\n ct_node\['minlumapixvalue'].clearAnimated()\n max_knob.clearAnimated()\n nuke.execute(ct_node, frame, frame)\n maxval = max(max_knob.getValue())\n maxval = round(maxval, 3)\n kmax = n\[ch]\n kmax.setValue(max(0, maxval-1))\n \nn = nuke.thisNode()\nframe = nuke.frame()\n\nct_nodes = \[nuke.toNode('\{0\}.\{1\}MAX'.format(n.fullName(), c)) for c in \['R', 'G', 'B']]\nlimits = \['cyan', 'magenta', 'yellow']\n\nfor i, ct_node in enumerate(ct_nodes):\n get_max(ct_node, limits\[i])" +STARTLINE}
addUserKnob {6 use_input_image l "use input image" t "Use the input image to calculate the max distance instead of the specified gamuts." -STARTLINE}
addUserKnob {26 ""}
addUserKnob {4 direction M {forward inverse}}
addUserKnob {20 info_tab l Info}
addUserKnob {26 info_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>GamutCompress</b><br>\nmaps out of gamut colors back into gamut.\n<br><br><a href=https://github.com/jedypod/gamut-compress>Documentation</a>"}
addUserKnob {20 doc_grp l "" +STARTLINE n 1}
doc_grp 0
addUserKnob {26 doc_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>Method</b><br>\nSpecify the tone compression curve to use when <br>\nmapping out of gamut colors into the boundary threshold.<br>\n<a href=https://www.desmos.com/calculator/hmzirlw7tj>log</a>\n<a href=https://www.desmos.com/calculator/lkhdtjbodx>reinhard</a>\n<a href=https://www.desmos.com/calculator/s2adnicmmr>exp</a>\n<a href=https://www.desmos.com/calculator/h96qmnozpo>atan</a>\n<a href=https://www.desmos.com/calculator/xiwliws24x>tanh</a>\n<br><br>\nThese curves are sorted by slope. Log is less steep and doesn't get as flat,<br>\nwhich results in more desaturation in compressed colors <br>\nat the same threshold. Tanh is more steep and gets flatter sooner<br>\nwhich causes colors to be more saturated at the same threshold. <br>\nYou may need to boost the threshold to get the desired color appearance with tanh.<br><br>\n\n<b>Threshold</b><br>\nPercentage of the gamut to affect. If threshold is 0.2, <br>\nthe inner 80% of the gamut will be unaffected and <br>\nout of gamut values will be compressed into <br>\nthe outer 20% of the gamut's color volume.<br><br>\n\n<b>Shadow Rolloff</b><br>\nReduce gamut compression in dark areas below specified value.<br>\nHelps reduce invertability issues in negative values from grain.<br><br>\n\n<b>Max Distance</b><br>\nPer color component control to specify what distance will be <br>\ncompressed to the gamut boundary. For example, <br>\na value of cyan=0.2 will map colors with a distance of red=1.2 from <br>\nthe achromatic axis to red=1.0, which is the gamut boundary.<br><br>\n\n<b>Calculate Max Distance</b><br>\nA helper to calculate the max distance that might occur when <br>\nmapping from a particular source color gamut. For example <br>\nwhen mapping from AlexaWideGamut to ACEScg, the max distance<br>\nof magenta will be highest and the other two components will be lower.<br>\nSetting these distance values according to the likely distances in the <br>\nsource gamut helps avoid unwanted shifts in color. The default is set to<br>\na good average among many digital cinema camera gamuts, but you may<br>\nwant to tweak these values for your needs.<br><br>\n<b>Direction</b><br>\nSpecifies whether to apply or inverse the gamut compression operation.<br><br>"}
addUserKnob {20 endGroup n -1}
addUserKnob {26 about_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\nWritten by <a href=https://github.com/jedypod color=red>Jed Smith</a> with <a href=https://community.acescentral.com/t/rgb-saturation-gamut-mapping-approach-and-a-comp-vfx-perspective>help</a> from the <a href=https://community.acescentral.com/c/aces-development-acesnext/vwg-aces-gamut-mapping-working-group>ACES Gamut Mapping VWG</a>"}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot4
xpos -6
ypos -174
}
set N99987f20 [stack 0]
Dot {
name Dot2
xpos -226
ypos -174
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -260
ypos -129
}
set N15af9c40 [stack 0]
Dot {
name Dot1
xpos -226
ypos -78
}
set N6642ad40 [stack 0]
Dot {
name Dot3
xpos -226
ypos 114
}
push $N6642ad40
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -81
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
set N9fbe2970 [stack 0]
Dot {
name Dot7
xpos -116
ypos 66
}
push $N15af9c40
push $N99987f20
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge1
xpos -40
ypos -129
}
push $N9fbe2970
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -81
}
Group {
name compress
knobChanged "from math import (pow, exp, log, tan, atan, atanh, cos, pi, fabs)\n\ndef i_log(x):\n return (exp((1-t+t*log(1-x)-x*t*log(1-x))/(t*(1-x))))*t+x*t-k\ndef i_exp(x):\n return -log((-x+1)/(t-x))*(-t+x)+t-k\ndef i_atan(x):\n return (2*tan((pi*(1-t))/(2*(x-t)))*(x-t))/pi+t-k\ndef i_tanh(x):\n return atanh((1-t)/(x-t))*(x-t)+t-k\ndef sign(x):\n return 0 if x == 0 else 1 if x > 0 else -1\n\ndef bisect(f, a, b):\n if sign(f(a)) == sign(f(b)): \n # bad estimate. return something close to linear\n if method == 'exp' or method == 'log':\n return -100\n else: \n return 1.99999\n c = (a+b)/2.0\n y = f(c)\n if fabs(y) <= tol:\n return c # lucky guess\n n = 1\n while fabs(y) > tol and n <= nmax:\n if sign(y) == sign(f(a)):\n a = c\n else:\n b = c\n c = (a+b)/2.0\n y = f(c)\n n += 1\n return c\n\ndef calc():\n a = 1.0001\n b = 5\n if method == 'log':\n f = i_log\n a = -50\n b = 0.98\n elif method == 'exp':\n f = i_exp\n elif method == 'atan':\n f = i_atan\n elif method == 'tanh':\n f = i_tanh\n a = 1.000001\n lim = bisect(f, a, b)\n return lim\n\nn = nuke.thisNode()\nknob = nuke.thisKnob()\n\nn.begin()\nif n\['method'].value() != 'reinhard':\n tol = 1e-3\n nmax = 100\n \n tk = n\['threshold']\n if tk.singleValue():\n thr = \[1-tk.getValue()]*3\n else:\n thr = \[1-v for v in tk.getValue()]\n\n method = n\['method'].value()\n\n k_knobs = \['cyan', 'magenta', 'yellow']\n lim_knobs = \['lim_x', 'lim_y', 'lim_z']\n if knob.name() in k_knobs:\n i = k_knobs.index(knob.name())\n lim_knob = lim_knobs\[i]\n t = thr\[i]\n k = knob.getValue()+1\n lim = calc()\n n\[lim_knob].setValue(lim)\n elif knob.name() == 'method' or knob.name() == 'threshold':\n for i, lknob in enumerate(lim_knobs):\n k = n\[k_knobs\[i]].getValue()+1\n t = thr\[i]\n lim = calc()\n n\[lknob].setValue(lim)\nn.end()"
xpos -40
ypos -25
addUserKnob {20 compress}
addUserKnob {4 method M {log reinhard exp atan tanh ""}}
method reinhard
addUserKnob {18 threshold}
threshold {0.3 0.3 0}
addUserKnob {6 threshold_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {7 cyan}
cyan 0.2
addUserKnob {7 magenta}
magenta 0.2
addUserKnob {7 yellow}
yellow 0.2
addUserKnob {26 ""}
addUserKnob {7 lim_x R -5 2}
lim_x 1.136815332
addUserKnob {7 lim_y R -5 2}
lim_y 1.322357568
addUserKnob {7 lim_z R -5 2}
lim_z 1.107519189
addUserKnob {26 ""}
addUserKnob {6 invert +STARTLINE}
invert {{parent.direction}}
}
Input {
inputs 0
name Input
xpos -40
ypos -202
}
Dot {
name Dot2
xpos -6
ypos -102
}
set N9998a870 [stack 0]
Dot {
name Dot1
xpos 324
ypos -30
}
set N51f48e0 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*log((1+(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x)))/(1-(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x))))/2
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*log((1+(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y)))/(1-(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y))))/2
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*log((1+(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z)))/(1-(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z))))/2
name uncompress_tanh
xpos 510
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N51f48e0
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*tan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*tan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*tan(pi/2*(b-thr_z)/(lim_z-thr_z))
name uncompress_atan
xpos 400
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N51f48e0
Expression {
expr0 r<thr_x?r:-log((r-lim_x)/(thr_x-lim_x))*(-thr_x+lim_x)+thr_x
expr1 g<thr_y?g:-log((g-lim_y)/(thr_y-lim_y))*(-thr_y+lim_y)+thr_y
expr2 b<thr_z?b:-log((b-lim_z)/(thr_z-lim_z))*(-thr_z+lim_z)+thr_z
name uncompress_exp
xpos 290
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N51f48e0
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)-1/(1-thr_x)+1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)-1/(1-thr_y)+1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)-1/(1-thr_z)+1/(lim_z-thr_z)))
name uncompress_reinhard
xpos 180
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.compress_reinhard.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.compress_reinhard.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.compress_reinhard.lim_z}}
}
push $N51f48e0
Expression {
expr0 r<thr_x?r:exp((r-thr_x+thr_x*log(1-lim_x)-lim_x*thr_x*log(1-lim_x))/(thr_x*(1-lim_x)))*thr_x+lim_x*thr_x
expr1 "g<thr_y?g:exp((g-thr_y+thr_y*log(1-lim_y)-lim_y*thr_y*log(1-lim_y))/(thr_y*(1-lim_y)))*thr_y+lim_y*thr_y\n"
expr2 b<thr_z?b:exp((b-thr_z+thr_z*log(1-lim_z)-lim_z*thr_z*log(1-lim_z))/(thr_z*(1-lim_z)))*thr_z+lim_z*thr_z
name uncompress_log
xpos 70
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method1
xpos 290
ypos 135
}
push $N9998a870
Dot {
name Dot6
xpos -336
ypos -30
}
set N34a452f0 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*tanh(((r-thr_x)/(lim_x-thr_x)))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*tanh(((g-thr_y)/(lim_y-thr_y)))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*tanh(((b-thr_z)/(lim_z-thr_z)))
name compress_tanh
xpos -150
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N34a452f0
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*atan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*atan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*atan(pi/2*(b-thr_z)/(lim_z-thr_z))
name compress_atan
xpos -260
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N34a452f0
Expression {
expr0 r<thr_x?r:lim_x-(lim_x-thr_x)*exp(-(((r-thr_x)*((lim_x)/(lim_x-thr_x))/lim_x)))
expr1 g<thr_y?g:lim_y-(lim_y-thr_y)*exp(-(((g-thr_y)*((lim_y)/(lim_y-thr_y))/lim_y)))
expr2 b<thr_z?b:lim_z-(lim_z-thr_z)*exp(-(((b-thr_z)*((lim_z)/(lim_z-thr_z))/lim_z)))
name compress_exp
xpos -370
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N34a452f0
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)+1/(1-thr_x)-1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)+1/(1-thr_y)-1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)+1/(1-thr_z)-1/(lim_z-thr_z)))
name compress_reinhard
xpos -480
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.cyan+1}}
addUserKnob {7 lim_y}
lim_y {{parent.magenta+1}}
addUserKnob {7 lim_z}
lim_z {{parent.yellow+1}}
}
push $N34a452f0
Expression {
expr0 r<thr_x?r:thr_x*log(r/thr_x-lim_x)-lim_x*thr_x*log(r/thr_x-lim_x)+thr_x-thr_x*log(1-lim_x)+lim_x*thr_x*log(1-lim_x)
expr1 g<thr_y?g:thr_y*log(g/thr_y-lim_y)-lim_y*thr_y*log(g/thr_y-lim_y)+thr_y-thr_y*log(1-lim_y)+lim_y*thr_y*log(1-lim_y)
expr2 b<thr_z?b:thr_z*log(b/thr_z-lim_z)-lim_z*thr_z*log(b/thr_z-lim_z)+thr_z-thr_z*log(1-lim_z)+lim_z*thr_z*log(1-lim_z)
name compress_log
xpos -590
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method
xpos -370
ypos 135
}
Switch {
inputs 2
which {{parent.invert}}
name switch_reverse
xpos -40
ypos 278
}
Output {
name Output
xpos -40
ypos 422
}
end_group
Merge2 {
inputs 2
operation multiply
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos 63
}
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge5
xpos -40
ypos 111
}
Output {
name Output
xpos -40
ypos 182
}
push $N99987f20
Group {
inputs 0
name RGB
xpos 180
ypos -274
}
Constant {
inputs 0
color {0 0 0 0}
format "4 1 0 0 4 1 1 rgbw"
name Constant3
note_font "Bitstream Vera Sans"
xpos 510
ypos -34
postage_stamp false
}
Reformat {
type "to box"
box_width 3
box_height 2
box_fixed true
name Reformat1
xpos 510
ypos -10
}
Rectangle {
area {0 0 1 2}
color {1 0 0 0}
name Rectangle1
note_font "Bitstream Vera Sans"
xpos 510
ypos 14
}
Rectangle {
area {1 0 2 2}
color {0 1 0 0}
name Rectangle2
note_font "Bitstream Vera Sans"
xpos 510
ypos 38
}
Rectangle {
area {2 0 3 2}
color {0 0 1 0}
name Rectangle3
note_font "Bitstream Vera Sans"
xpos 510
ypos 62
}
Output {
name Output
xpos 510
ypos 110
}
end_group
Group {
name Gamut
xpos 180
ypos -226
addUserKnob {20 GamutToXYZ_tab l GamutToXYZ}
addUserKnob {4 gamut_in l "gamut in" t "Choose source gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_in ACEScg
addUserKnob {4 gamut_out l "gamut out" t "Choose destination gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_out "Arri AlexaWideGamut"
addUserKnob {6 invert +STARTLINE}
invert true
}
Input {
inputs 0
name Input
xpos -40
ypos -130
}
Dot {
name Dot1
xpos -6
ypos -78
}
set Na8ae90d0 [stack 0]
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name ColorMatrix2
label "RGB to XYZ"
xpos 180
ypos 32
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9872239828 -0.006113247015 0.01595330238}
{-0.007598329335 1.001861453 0.005330037326}
{0.00307257846 -0.00509596616 1.081680536}
}
invert {{!parent.ColorMatrix4.invert}}
name ColorMatrix1
label "CAT: Bradford\n ACES to D65"
xpos 180
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name ColorMatrix3
label "XYZ to RGB"
xpos 180
ypos 176
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
push $Na8ae90d0
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name RGBtoXYZ
xpos -260
ypos 38
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9874471426 -0.005980737507 0.01595583558}
{-0.00739388587 1.001675606 0.005319938064}
{0.003088310361 -0.005131930113 1.081959367}
}
invert {{"parent.RGBtoXYZ.wxy == 0.3127"}}
name ColorMatrix4
label "CAT: Bradford\n D60 to D65"
xpos -260
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name XYZtoRGB
xpos -260
ypos 182
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
Switch {
inputs 2
which {{parent.invert}}
name switch_direction
xpos -40
ypos 303
}
Output {
name Output
xpos -40
ypos 374
}
push $Na8ae90d0
ColorMatrix {
matrix {
{{curve 0.9525524378 0.6624541879 0.7053968906 0.4123907983 0.6369580626 0.5049495697 0.4865709841 0.6380076408 0.7352752686 0.5022571683 0.7160496712 0.7064827085 0.5990839601 0.6796444654 0.6481720209 0.6065810919 0.7165006995 0.7976718545} {curve 0 0.1340042055 0.1640413404 0.3575843275 0.1446169019 0.2646814585 0.2656676769 0.2147038579 0.06860940903 0.2929667532 0.1296834797 0.1288010478 0.2489254922 0.1522114277 0.1940581352 0.2203479856 0.1010205746 0.1351878047} {curve 9.367863095e-05 0.1561876982 0.08101774752 0.180480808 0.1688809693 0.1830150485 0.1982172877 0.09774444997 0.1465712637 0.1552320272 0.1047228053 0.1151721701 0.1024464965 0.1186000481 0.108225815 0.123526901 0.1467743814 0.03133957833}}
{{curve 0.3439664543 0.2722287476 0.2801307142 0.2126390189 0.2627002299 0.237623319 0.2289745659 0.2919537723 0.2866941094 0.1387997568 0.2612613738 0.2709796727 0.2150758505 0.2606855333 0.2830046713 0.2680045366 0.258728236 0.2880405784} {curve 0.7281661034 0.6740817428 0.8202066422 0.7151686549 0.6779980659 0.6891706586 0.6917385459 0.8238410354 0.8429791331 0.910841465 0.8696421385 0.786606431 0.8850684762 0.7748944759 0.8131960034 0.8326833844 0.7246823311 0.7118694782} {curve -0.07213255018 0.05368951708 -0.1003373638 0.07219231874 0.05930171534 0.07320601493 0.07928691059 -0.1157948226 -0.1296732277 -0.04964122549 -0.1309035122 -0.05758608505 -0.1001443192 -0.03558001295 -0.09620071948 -0.1006879359 0.01658944227 8.991353388e-05}}
{{curve -3.863927134e-08 -0.005574660841 -0.1037815213 0.01933082007 0 0 0 0.0027982709 -0.07968087494 0.07801423222 -0.009676366113 -0.009677864611 -0.03206583485 -0.009310216643 -0.01825834997 -0.02941203304 -2.906408625e-08 0} {curve 0 0.004060741514 -0.07290724665 0.1191947311 0.0280726999 0.0449459292 0.04511339962 -0.06703422964 -0.3473432064 -0.3148325086 -0.2364816219 0.004600019194 -0.02765839547 -0.004612449091 -0.08316776901 -0.08659287542 0.05121183768 -1.262213711e-08} {curve 1.008825183 1.010339141 1.265746474 0.950532198 1.060985088 0.9638792276 1.043944359 1.153293729 1.51608181 1.325875998 1.335215807 1.094135642 1.148782015 1.102980375 1.190483928 1.205062628 0.7738927603 0.8248898983}}
}
name mtx
label "\n"
xpos -40
ypos 38
addUserKnob {20 Params}
addUserKnob {12 rxy}
rxy {{curve 0.7347 0.713 0.8 0.64 0.708 0.68 0.68 0.684 0.780308 0.69848046 0.74 0.73 0.766 0.73 0.71 0.7177 0.7347 0.734699} {curve 0.2653 0.293 0.3177 0.33 0.292 0.32 0.32 0.313 0.304253 0.19302645 0.27 0.28 0.275 0.28 0.31 0.3171 0.2653 0.265301}}
addUserKnob {12 gxy}
gxy {{curve 0 0.165 0.18 0.3 0.17 0.265 0.265 0.221 0.121595 0.32955538 0.17 0.14 0.225 0.165 0.21 0.228 0.1152 0.159597} {curve 1 0.83 0.9 0.6 0.797 0.69 0.69 0.848 1.493994 1.02459662 1.14 0.855 0.8 0.84 0.88 0.8616 0.8264 0.840403}}
addUserKnob {12 bxy}
bxy {{curve 0.0001 0.128 0.065 0.15 0.131 0.15 0.15 0.0861 0.095612 0.10844263 0.08 0.1 0.089 0.1 0.09 0.1006 0.1566 0.036598} {curve -0.077 0.044 -0.0805 0.06 0.046 0.06 0.06 -0.102 -0.084589 -0.03467857 -0.1 -0.05 -0.087 -0.03 -0.08 -0.082 0.0177 0.000105}}
addUserKnob {12 wxy}
wxy {{curve 0.32168 0.32168 0.3127 0.3127 0.3127 0.32168 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3457 0.345704} {curve 0.33767 0.33767 0.329 0.329 0.329 0.33767 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.3585 0.35854}}
}
end_group
Switch {
inputs 2
which {{parent.use_input_image}}
name Switch_distance_source
xpos 180
ypos -177
}
Group {
name ColorDistance
xpos 180
ypos -130
addUserKnob {20 ColorDistance}
addUserKnob {7 shd_rolloff l "shd rolloff" R 0 0.1}
shd_rolloff {{parent.shd_rolloff}}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot5
xpos -6
ypos -222
}
set Nc713a700 [stack 0]
Dot {
name Dot1
xpos -116
ypos -222
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -150
ypos -177
}
set N6f1433a0 [stack 0]
push $Nc713a700
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -177
}
push $N6f1433a0
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -129
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos -129
}
Output {
name Output
xpos -40
ypos -58
}
end_group
CurveTool {
operation "Max Luma Pixel"
channels {rgba.red -rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve} {curve}}
maxlumapixvalue {{curve} {curve} 0}
minlumapixdata {{curve} {curve}}
minlumapixvalue {{curve} {curve} 0}
name RMAX
tile_color 0x84000000
xpos 180
ypos -81
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x2 2} {curve x2 0}}
maxlumapixvalue {{curve x2 0} {curve x2 1.218766689} 0}
minlumapixdata {{curve x2 1} {curve x2 0}}
minlumapixvalue {{curve x2 0} {curve x2 0} 0}
name GMAX
tile_color 0x84000000
xpos 180
ypos -57
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red -rgba.green rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x2 1} {curve x2 0}}
maxlumapixvalue {{curve x2 0} {curve x2 0} 1.052656531}
minlumapixdata {{curve x2 2} {curve x2 0}}
minlumapixvalue {{curve x2 0} {curve x2 0} 0}
name BMAX
tile_color 0x84000000
xpos 180
ypos -33
}
end_group
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "reinhard: thr 0.3 lim 0.2"
old_message {{114 101 105 110 104 97 114 100 58 32 116 104 114 32 48 46 51 32 108 105 109 32 48 46 50}
}
box {2.25 -0.625 285 41.625}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 11 24 12 24 13 24 14 24 15 24 16 24 17 24 18 24 19 24 20 24 21 24 22 24 23 24 24 24}
}
cursor_position 8
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text3
note_font Helvetica
selected true
xpos 8760
ypos 8460
}
push $N51f0100
Group {
name GamutCompress13
label "\[value method]: \[value direction]\nthreshold increased"
selected true
xpos 8650
ypos 8402
addUserKnob {20 GamutCompress}
addUserKnob {41 method T compress.method}
addUserKnob {22 reset t "Reset knobs to default values. Distance limits are calculated based on an the average of a selection of digital cinema cameras." -STARTLINE T "n = nuke.thisNode()\nnuke.root().begin()\ndefaults = \{\n 'threshold': 0.2,\n 'shd_rolloff': 0.03,\n 'cyan': 0.09,\n 'magenta':0.24,\n 'yellow': 0.12,\n\}\nfor k, v in defaults.items():\n n\[k].setValue(v)"}
addUserKnob {41 threshold t "Percentage of the outer gamut boundary to affect. A value of 0.2 means 20% of the outer gamut will be utilized for gamut compression." T compress.threshold}
addUserKnob {7 shd_rolloff l "shd rolloff" t "Shadow rolloff reduces the gamut compression effect below the specified pixel value. This reduces invertability issues with negative pixels in shadow grain." R 0 0.1}
shd_rolloff 0.03
addUserKnob {26 distance_limit_label l " " t "Specifies the distance beyond the gamut boundary to map to the gamut boundary for each color component." T "<b>distance limit"}
addUserKnob {41 cyan t "Maximum distance beyond the green-blue gamut boundary to compress to the gamut boundary." T compress.cyan}
addUserKnob {41 magenta t "Maximum distance beyond the blue-red gamut boundary to compress to the gamut boundary." T compress.magenta}
addUserKnob {41 yellow t "Maximum distance beyond the red-green gamut boundary to compress to the gamut boundary." T compress.yellow}
addUserKnob {26 ""}
addUserKnob {26 calculate_distance_limit_label l " " T "<b>calculate distance limit"}
addUserKnob {41 gamut t "The current gamut in which we are working." T Gamut.gamut_in}
addUserKnob {41 src_gamut l "source gamut" t "The source gamut from which this image was transformed." -STARTLINE T Gamut.gamut_out}
addUserKnob {22 calc_max_limit l "Calc Max Distance" t "Calculate the max distance given current gamut and source gamut." T "def get_max(ct_node, ch):\n max_knob = ct_node\['maxlumapixvalue']\n ct_node\['maxlumapixdata'].clearAnimated()\n ct_node\['minlumapixdata'].clearAnimated()\n ct_node\['minlumapixvalue'].clearAnimated()\n max_knob.clearAnimated()\n nuke.execute(ct_node, frame, frame)\n maxval = max(max_knob.getValue())\n maxval = round(maxval, 3)\n kmax = n\[ch]\n kmax.setValue(max(0, maxval-1))\n \nn = nuke.thisNode()\nframe = nuke.frame()\n\nct_nodes = \[nuke.toNode('\{0\}.\{1\}MAX'.format(n.fullName(), c)) for c in \['R', 'G', 'B']]\nlimits = \['cyan', 'magenta', 'yellow']\n\nfor i, ct_node in enumerate(ct_nodes):\n get_max(ct_node, limits\[i])" +STARTLINE}
addUserKnob {6 use_input_image l "use input image" t "Use the input image to calculate the max distance instead of the specified gamuts." -STARTLINE}
addUserKnob {26 ""}
addUserKnob {4 direction M {forward inverse}}
addUserKnob {20 info_tab l Info}
addUserKnob {26 info_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>GamutCompress</b><br>\nmaps out of gamut colors back into gamut.\n<br><br><a href=https://github.com/jedypod/gamut-compress>Documentation</a>"}
addUserKnob {20 doc_grp l "" +STARTLINE n 1}
doc_grp 0
addUserKnob {26 doc_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>Method</b><br>\nSpecify the tone compression curve to use when <br>\nmapping out of gamut colors into the boundary threshold.<br>\n<a href=https://www.desmos.com/calculator/hmzirlw7tj>log</a>\n<a href=https://www.desmos.com/calculator/lkhdtjbodx>reinhard</a>\n<a href=https://www.desmos.com/calculator/s2adnicmmr>exp</a>\n<a href=https://www.desmos.com/calculator/h96qmnozpo>atan</a>\n<a href=https://www.desmos.com/calculator/xiwliws24x>tanh</a>\n<br><br>\nThese curves are sorted by slope. Log is less steep and doesn't get as flat,<br>\nwhich results in more desaturation in compressed colors <br>\nat the same threshold. Tanh is more steep and gets flatter sooner<br>\nwhich causes colors to be more saturated at the same threshold. <br>\nYou may need to boost the threshold to get the desired color appearance with tanh.<br><br>\n\n<b>Threshold</b><br>\nPercentage of the gamut to affect. If threshold is 0.2, <br>\nthe inner 80% of the gamut will be unaffected and <br>\nout of gamut values will be compressed into <br>\nthe outer 20% of the gamut's color volume.<br><br>\n\n<b>Shadow Rolloff</b><br>\nReduce gamut compression in dark areas below specified value.<br>\nHelps reduce invertability issues in negative values from grain.<br><br>\n\n<b>Max Distance</b><br>\nPer color component control to specify what distance will be <br>\ncompressed to the gamut boundary. For example, <br>\na value of cyan=0.2 will map colors with a distance of red=1.2 from <br>\nthe achromatic axis to red=1.0, which is the gamut boundary.<br><br>\n\n<b>Calculate Max Distance</b><br>\nA helper to calculate the max distance that might occur when <br>\nmapping from a particular source color gamut. For example <br>\nwhen mapping from AlexaWideGamut to ACEScg, the max distance<br>\nof magenta will be highest and the other two components will be lower.<br>\nSetting these distance values according to the likely distances in the <br>\nsource gamut helps avoid unwanted shifts in color. The default is set to<br>\na good average among many digital cinema camera gamuts, but you may<br>\nwant to tweak these values for your needs.<br><br>\n<b>Direction</b><br>\nSpecifies whether to apply or inverse the gamut compression operation.<br><br>"}
addUserKnob {20 endGroup n -1}
addUserKnob {26 about_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\nWritten by <a href=https://github.com/jedypod color=red>Jed Smith</a> with <a href=https://community.acescentral.com/t/rgb-saturation-gamut-mapping-approach-and-a-comp-vfx-perspective>help</a> from the <a href=https://community.acescentral.com/c/aces-development-acesnext/vwg-aces-gamut-mapping-working-group>ACES Gamut Mapping VWG</a>"}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot4
xpos -6
ypos -174
}
set Nd2a75620 [stack 0]
Dot {
name Dot2
xpos -226
ypos -174
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -260
ypos -129
}
set Nd2477120 [stack 0]
Dot {
name Dot1
xpos -226
ypos -78
}
set Na1185060 [stack 0]
Dot {
name Dot3
xpos -226
ypos 114
}
push $Na1185060
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -81
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
set Nadf7cf70 [stack 0]
Dot {
name Dot7
xpos -116
ypos 66
}
push $Nd2477120
push $Nd2a75620
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge1
xpos -40
ypos -129
}
push $Nadf7cf70
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -81
}
Group {
name compress
knobChanged "from math import (pow, exp, log, tan, atan, atanh, cos, pi, fabs)\n\ndef i_log(x):\n return (exp((1-t+t*log(1-x)-x*t*log(1-x))/(t*(1-x))))*t+x*t-k\ndef i_exp(x):\n return -log((-x+1)/(t-x))*(-t+x)+t-k\ndef i_atan(x):\n return (2*tan((pi*(1-t))/(2*(x-t)))*(x-t))/pi+t-k\ndef i_tanh(x):\n return atanh((1-t)/(x-t))*(x-t)+t-k\ndef sign(x):\n return 0 if x == 0 else 1 if x > 0 else -1\n\ndef bisect(f, a, b):\n if sign(f(a)) == sign(f(b)): \n # bad estimate. return something close to linear\n if method == 'exp' or method == 'log':\n return -100\n else: \n return 1.99999\n c = (a+b)/2.0\n y = f(c)\n if fabs(y) <= tol:\n return c # lucky guess\n n = 1\n while fabs(y) > tol and n <= nmax:\n if sign(y) == sign(f(a)):\n a = c\n else:\n b = c\n c = (a+b)/2.0\n y = f(c)\n n += 1\n return c\n\ndef calc():\n a = 1.0001\n b = 5\n if method == 'log':\n f = i_log\n a = -50\n b = 0.98\n elif method == 'exp':\n f = i_exp\n elif method == 'atan':\n f = i_atan\n elif method == 'tanh':\n f = i_tanh\n a = 1.000001\n lim = bisect(f, a, b)\n return lim\n\nn = nuke.thisNode()\nknob = nuke.thisKnob()\n\nn.begin()\nif n\['method'].value() != 'reinhard':\n tol = 1e-3\n nmax = 100\n \n tk = n\['threshold']\n if tk.singleValue():\n thr = \[1-tk.getValue()]*3\n else:\n thr = \[1-v for v in tk.getValue()]\n\n method = n\['method'].value()\n\n k_knobs = \['cyan', 'magenta', 'yellow']\n lim_knobs = \['lim_x', 'lim_y', 'lim_z']\n if knob.name() in k_knobs:\n i = k_knobs.index(knob.name())\n lim_knob = lim_knobs\[i]\n t = thr\[i]\n k = knob.getValue()+1\n lim = calc()\n n\[lim_knob].setValue(lim)\n elif knob.name() == 'method' or knob.name() == 'threshold':\n for i, lknob in enumerate(lim_knobs):\n k = n\[k_knobs\[i]].getValue()+1\n t = thr\[i]\n lim = calc()\n n\[lknob].setValue(lim)\nn.end()"
xpos -40
ypos -25
addUserKnob {20 compress}
addUserKnob {4 method M {log reinhard exp atan tanh ""}}
method tanh
addUserKnob {18 threshold}
threshold 0.5
addUserKnob {6 threshold_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {7 cyan}
cyan 0.2
addUserKnob {7 magenta}
magenta 0.2
addUserKnob {7 yellow}
yellow 0.2
addUserKnob {26 ""}
addUserKnob {7 lim_x R -5 2}
lim_x 1.113282222
addUserKnob {7 lim_y R -5 2}
lim_y 1.113282222
addUserKnob {7 lim_z R -5 2}
lim_z 1.113282222
addUserKnob {26 ""}
addUserKnob {6 invert +STARTLINE}
invert {{parent.direction}}
}
Input {
inputs 0
name Input
xpos -40
ypos -202
}
Dot {
name Dot2
xpos -6
ypos -102
}
set N9a687620 [stack 0]
Dot {
name Dot1
xpos 324
ypos -30
}
set N9517e600 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*log((1+(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x)))/(1-(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x))))/2
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*log((1+(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y)))/(1-(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y))))/2
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*log((1+(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z)))/(1-(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z))))/2
name uncompress_tanh
xpos 510
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N9517e600
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*tan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*tan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*tan(pi/2*(b-thr_z)/(lim_z-thr_z))
name uncompress_atan
xpos 400
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N9517e600
Expression {
expr0 r<thr_x?r:-log((r-lim_x)/(thr_x-lim_x))*(-thr_x+lim_x)+thr_x
expr1 g<thr_y?g:-log((g-lim_y)/(thr_y-lim_y))*(-thr_y+lim_y)+thr_y
expr2 b<thr_z?b:-log((b-lim_z)/(thr_z-lim_z))*(-thr_z+lim_z)+thr_z
name uncompress_exp
xpos 290
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N9517e600
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)-1/(1-thr_x)+1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)-1/(1-thr_y)+1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)-1/(1-thr_z)+1/(lim_z-thr_z)))
name uncompress_reinhard
xpos 180
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.compress_reinhard.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.compress_reinhard.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.compress_reinhard.lim_z}}
}
push $N9517e600
Expression {
expr0 r<thr_x?r:exp((r-thr_x+thr_x*log(1-lim_x)-lim_x*thr_x*log(1-lim_x))/(thr_x*(1-lim_x)))*thr_x+lim_x*thr_x
expr1 "g<thr_y?g:exp((g-thr_y+thr_y*log(1-lim_y)-lim_y*thr_y*log(1-lim_y))/(thr_y*(1-lim_y)))*thr_y+lim_y*thr_y\n"
expr2 b<thr_z?b:exp((b-thr_z+thr_z*log(1-lim_z)-lim_z*thr_z*log(1-lim_z))/(thr_z*(1-lim_z)))*thr_z+lim_z*thr_z
name uncompress_log
xpos 70
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method1
xpos 290
ypos 135
}
push $N9a687620
Dot {
name Dot6
xpos -336
ypos -30
}
set Ndf131220 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*tanh(((r-thr_x)/(lim_x-thr_x)))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*tanh(((g-thr_y)/(lim_y-thr_y)))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*tanh(((b-thr_z)/(lim_z-thr_z)))
name compress_tanh
xpos -150
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Ndf131220
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*atan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*atan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*atan(pi/2*(b-thr_z)/(lim_z-thr_z))
name compress_atan
xpos -260
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Ndf131220
Expression {
expr0 r<thr_x?r:lim_x-(lim_x-thr_x)*exp(-(((r-thr_x)*((lim_x)/(lim_x-thr_x))/lim_x)))
expr1 g<thr_y?g:lim_y-(lim_y-thr_y)*exp(-(((g-thr_y)*((lim_y)/(lim_y-thr_y))/lim_y)))
expr2 b<thr_z?b:lim_z-(lim_z-thr_z)*exp(-(((b-thr_z)*((lim_z)/(lim_z-thr_z))/lim_z)))
name compress_exp
xpos -370
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Ndf131220
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)+1/(1-thr_x)-1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)+1/(1-thr_y)-1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)+1/(1-thr_z)-1/(lim_z-thr_z)))
name compress_reinhard
xpos -480
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.cyan+1}}
addUserKnob {7 lim_y}
lim_y {{parent.magenta+1}}
addUserKnob {7 lim_z}
lim_z {{parent.yellow+1}}
}
push $Ndf131220
Expression {
expr0 r<thr_x?r:thr_x*log(r/thr_x-lim_x)-lim_x*thr_x*log(r/thr_x-lim_x)+thr_x-thr_x*log(1-lim_x)+lim_x*thr_x*log(1-lim_x)
expr1 g<thr_y?g:thr_y*log(g/thr_y-lim_y)-lim_y*thr_y*log(g/thr_y-lim_y)+thr_y-thr_y*log(1-lim_y)+lim_y*thr_y*log(1-lim_y)
expr2 b<thr_z?b:thr_z*log(b/thr_z-lim_z)-lim_z*thr_z*log(b/thr_z-lim_z)+thr_z-thr_z*log(1-lim_z)+lim_z*thr_z*log(1-lim_z)
name compress_log
xpos -590
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method
xpos -370
ypos 135
}
Switch {
inputs 2
which {{parent.invert}}
name switch_reverse
xpos -40
ypos 278
}
Output {
name Output
xpos -40
ypos 422
}
end_group
Merge2 {
inputs 2
operation multiply
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos 63
}
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge5
xpos -40
ypos 111
}
Output {
name Output
xpos -40
ypos 182
}
push $Nd2a75620
Group {
inputs 0
name RGB
xpos 180
ypos -274
}
Constant {
inputs 0
color {0 0 0 0}
format "4 1 0 0 4 1 1 rgbw"
name Constant3
note_font "Bitstream Vera Sans"
xpos 510
ypos -34
postage_stamp false
}
Reformat {
type "to box"
box_width 3
box_height 2
box_fixed true
name Reformat1
xpos 510
ypos -10
}
Rectangle {
area {0 0 1 2}
color {1 0 0 0}
name Rectangle1
note_font "Bitstream Vera Sans"
xpos 510
ypos 14
}
Rectangle {
area {1 0 2 2}
color {0 1 0 0}
name Rectangle2
note_font "Bitstream Vera Sans"
xpos 510
ypos 38
}
Rectangle {
area {2 0 3 2}
color {0 0 1 0}
name Rectangle3
note_font "Bitstream Vera Sans"
xpos 510
ypos 62
}
Output {
name Output
xpos 510
ypos 110
}
end_group
Group {
name Gamut
xpos 180
ypos -226
addUserKnob {20 GamutToXYZ_tab l GamutToXYZ}
addUserKnob {4 gamut_in l "gamut in" t "Choose source gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_in ACEScg
addUserKnob {4 gamut_out l "gamut out" t "Choose destination gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_out "Arri AlexaWideGamut"
addUserKnob {6 invert +STARTLINE}
invert true
}
Input {
inputs 0
name Input
xpos -40
ypos -130
}
Dot {
name Dot1
xpos -6
ypos -78
}
set N9967f0b0 [stack 0]
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name ColorMatrix2
label "RGB to XYZ"
xpos 180
ypos 32
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9872239828 -0.006113247015 0.01595330238}
{-0.007598329335 1.001861453 0.005330037326}
{0.00307257846 -0.00509596616 1.081680536}
}
invert {{!parent.ColorMatrix4.invert}}
name ColorMatrix1
label "CAT: Bradford\n ACES to D65"
xpos 180
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name ColorMatrix3
label "XYZ to RGB"
xpos 180
ypos 176
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
push $N9967f0b0
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name RGBtoXYZ
xpos -260
ypos 38
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9874471426 -0.005980737507 0.01595583558}
{-0.00739388587 1.001675606 0.005319938064}
{0.003088310361 -0.005131930113 1.081959367}
}
invert {{"parent.RGBtoXYZ.wxy == 0.3127"}}
name ColorMatrix4
label "CAT: Bradford\n D60 to D65"
xpos -260
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name XYZtoRGB
xpos -260
ypos 182
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
Switch {
inputs 2
which {{parent.invert}}
name switch_direction
xpos -40
ypos 303
}
Output {
name Output
xpos -40
ypos 374
}
push $N9967f0b0
ColorMatrix {
matrix {
{{curve 0.9525524378 0.6624541879 0.7053968906 0.4123907983 0.6369580626 0.5049495697 0.4865709841 0.6380076408 0.7352752686 0.5022571683 0.7160496712 0.7064827085 0.5990839601 0.6796444654 0.6481720209 0.6065810919 0.7165006995 0.7976718545} {curve 0 0.1340042055 0.1640413404 0.3575843275 0.1446169019 0.2646814585 0.2656676769 0.2147038579 0.06860940903 0.2929667532 0.1296834797 0.1288010478 0.2489254922 0.1522114277 0.1940581352 0.2203479856 0.1010205746 0.1351878047} {curve 9.367863095e-05 0.1561876982 0.08101774752 0.180480808 0.1688809693 0.1830150485 0.1982172877 0.09774444997 0.1465712637 0.1552320272 0.1047228053 0.1151721701 0.1024464965 0.1186000481 0.108225815 0.123526901 0.1467743814 0.03133957833}}
{{curve 0.3439664543 0.2722287476 0.2801307142 0.2126390189 0.2627002299 0.237623319 0.2289745659 0.2919537723 0.2866941094 0.1387997568 0.2612613738 0.2709796727 0.2150758505 0.2606855333 0.2830046713 0.2680045366 0.258728236 0.2880405784} {curve 0.7281661034 0.6740817428 0.8202066422 0.7151686549 0.6779980659 0.6891706586 0.6917385459 0.8238410354 0.8429791331 0.910841465 0.8696421385 0.786606431 0.8850684762 0.7748944759 0.8131960034 0.8326833844 0.7246823311 0.7118694782} {curve -0.07213255018 0.05368951708 -0.1003373638 0.07219231874 0.05930171534 0.07320601493 0.07928691059 -0.1157948226 -0.1296732277 -0.04964122549 -0.1309035122 -0.05758608505 -0.1001443192 -0.03558001295 -0.09620071948 -0.1006879359 0.01658944227 8.991353388e-05}}
{{curve -3.863927134e-08 -0.005574660841 -0.1037815213 0.01933082007 0 0 0 0.0027982709 -0.07968087494 0.07801423222 -0.009676366113 -0.009677864611 -0.03206583485 -0.009310216643 -0.01825834997 -0.02941203304 -2.906408625e-08 0} {curve 0 0.004060741514 -0.07290724665 0.1191947311 0.0280726999 0.0449459292 0.04511339962 -0.06703422964 -0.3473432064 -0.3148325086 -0.2364816219 0.004600019194 -0.02765839547 -0.004612449091 -0.08316776901 -0.08659287542 0.05121183768 -1.262213711e-08} {curve 1.008825183 1.010339141 1.265746474 0.950532198 1.060985088 0.9638792276 1.043944359 1.153293729 1.51608181 1.325875998 1.335215807 1.094135642 1.148782015 1.102980375 1.190483928 1.205062628 0.7738927603 0.8248898983}}
}
name mtx
label "\n"
xpos -40
ypos 38
addUserKnob {20 Params}
addUserKnob {12 rxy}
rxy {{curve 0.7347 0.713 0.8 0.64 0.708 0.68 0.68 0.684 0.780308 0.69848046 0.74 0.73 0.766 0.73 0.71 0.7177 0.7347 0.734699} {curve 0.2653 0.293 0.3177 0.33 0.292 0.32 0.32 0.313 0.304253 0.19302645 0.27 0.28 0.275 0.28 0.31 0.3171 0.2653 0.265301}}
addUserKnob {12 gxy}
gxy {{curve 0 0.165 0.18 0.3 0.17 0.265 0.265 0.221 0.121595 0.32955538 0.17 0.14 0.225 0.165 0.21 0.228 0.1152 0.159597} {curve 1 0.83 0.9 0.6 0.797 0.69 0.69 0.848 1.493994 1.02459662 1.14 0.855 0.8 0.84 0.88 0.8616 0.8264 0.840403}}
addUserKnob {12 bxy}
bxy {{curve 0.0001 0.128 0.065 0.15 0.131 0.15 0.15 0.0861 0.095612 0.10844263 0.08 0.1 0.089 0.1 0.09 0.1006 0.1566 0.036598} {curve -0.077 0.044 -0.0805 0.06 0.046 0.06 0.06 -0.102 -0.084589 -0.03467857 -0.1 -0.05 -0.087 -0.03 -0.08 -0.082 0.0177 0.000105}}
addUserKnob {12 wxy}
wxy {{curve 0.32168 0.32168 0.3127 0.3127 0.3127 0.32168 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3457 0.345704} {curve 0.33767 0.33767 0.329 0.329 0.329 0.33767 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.3585 0.35854}}
}
end_group
Switch {
inputs 2
which {{parent.use_input_image}}
name Switch_distance_source
xpos 180
ypos -177
}
Group {
name ColorDistance
xpos 180
ypos -130
addUserKnob {20 ColorDistance}
addUserKnob {7 shd_rolloff l "shd rolloff" R 0 0.1}
shd_rolloff {{parent.shd_rolloff}}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot5
xpos -6
ypos -222
}
set Nd2e6b3e0 [stack 0]
Dot {
name Dot1
xpos -116
ypos -222
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -150
ypos -177
}
set N153f2230 [stack 0]
push $Nd2e6b3e0
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -177
}
push $N153f2230
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -129
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos -129
}
Output {
name Output
xpos -40
ypos -58
}
end_group
CurveTool {
operation "Max Luma Pixel"
channels {rgba.red -rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve} {curve}}
maxlumapixvalue {{curve} {curve} 0}
minlumapixdata {{curve} {curve}}
minlumapixvalue {{curve} {curve} 0}
name RMAX
tile_color 0x84000000
xpos 180
ypos -81
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x1 2} {curve x1 0}}
maxlumapixvalue {{curve x1 0} {curve x1 1.218766689} 0}
minlumapixdata {{curve x1 1} {curve x1 0}}
minlumapixvalue {{curve x1 0} {curve x1 0} 0}
name GMAX
tile_color 0x84000000
xpos 180
ypos -57
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red -rgba.green rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x1 1} {curve x1 0}}
maxlumapixvalue {{curve x1 0} {curve x1 0} 1.052656531}
minlumapixdata {{curve x1 2} {curve x1 0}}
minlumapixvalue {{curve x1 0} {curve x1 0} 0}
name BMAX
tile_color 0x84000000
xpos 180
ypos -33
}
end_group
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "tanh: thr 0.5 lim 0.2"
old_message {{116 97 110 104 58 32 116 104 114 32 48 46 53 32 108 105 109 32 48 46 50}
}
box {2.25 -0.625 229.75 41.625}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 11 24 12 24 13 24 14 24 15 24 16 24 17 24 18 24 19 24 20 24 0 50}
}
cursor_position 12
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text2
note_font Helvetica
selected true
xpos 8650
ypos 8458
}
push $N51f0100
Group {
name GamutCompress11
label "\[value method]: \[value direction]\nDefaults"
selected true
xpos 8540
ypos 8402
addUserKnob {20 GamutCompress}
addUserKnob {41 method T compress.method}
addUserKnob {22 reset t "Reset knobs to default values. Distance limits are calculated based on an the average of a selection of digital cinema cameras." -STARTLINE T "n = nuke.thisNode()\nnuke.root().begin()\ndefaults = \{\n 'threshold': 0.2,\n 'shd_rolloff': 0.03,\n 'cyan': 0.09,\n 'magenta':0.24,\n 'yellow': 0.12,\n\}\nfor k, v in defaults.items():\n n\[k].setValue(v)"}
addUserKnob {41 threshold t "Percentage of the outer gamut boundary to affect. A value of 0.2 means 20% of the outer gamut will be utilized for gamut compression." T compress.threshold}
addUserKnob {7 shd_rolloff l "shd rolloff" t "Shadow rolloff reduces the gamut compression effect below the specified pixel value. This reduces invertability issues with negative pixels in shadow grain." R 0 0.1}
shd_rolloff 0.03
addUserKnob {26 distance_limit_label l " " t "Specifies the distance beyond the gamut boundary to map to the gamut boundary for each color component." T "<b>distance limit"}
addUserKnob {41 cyan t "Maximum distance beyond the green-blue gamut boundary to compress to the gamut boundary." T compress.cyan}
addUserKnob {41 magenta t "Maximum distance beyond the blue-red gamut boundary to compress to the gamut boundary." T compress.magenta}
addUserKnob {41 yellow t "Maximum distance beyond the red-green gamut boundary to compress to the gamut boundary." T compress.yellow}
addUserKnob {26 ""}
addUserKnob {26 calculate_distance_limit_label l " " T "<b>calculate distance limit"}
addUserKnob {41 gamut t "The current gamut in which we are working." T Gamut.gamut_in}
addUserKnob {41 src_gamut l "source gamut" t "The source gamut from which this image was transformed." -STARTLINE T Gamut.gamut_out}
addUserKnob {22 calc_max_limit l "Calc Max Distance" t "Calculate the max distance given current gamut and source gamut." T "def get_max(ct_node, ch):\n max_knob = ct_node\['maxlumapixvalue']\n ct_node\['maxlumapixdata'].clearAnimated()\n ct_node\['minlumapixdata'].clearAnimated()\n ct_node\['minlumapixvalue'].clearAnimated()\n max_knob.clearAnimated()\n nuke.execute(ct_node, frame, frame)\n maxval = max(max_knob.getValue())\n maxval = round(maxval, 3)\n kmax = n\[ch]\n kmax.setValue(max(0, maxval-1))\n \nn = nuke.thisNode()\nframe = nuke.frame()\n\nct_nodes = \[nuke.toNode('\{0\}.\{1\}MAX'.format(n.fullName(), c)) for c in \['R', 'G', 'B']]\nlimits = \['cyan', 'magenta', 'yellow']\n\nfor i, ct_node in enumerate(ct_nodes):\n get_max(ct_node, limits\[i])" +STARTLINE}
addUserKnob {6 use_input_image l "use input image" t "Use the input image to calculate the max distance instead of the specified gamuts." -STARTLINE}
addUserKnob {26 ""}
addUserKnob {4 direction M {forward inverse}}
addUserKnob {20 info_tab l Info}
addUserKnob {26 info_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>GamutCompress</b><br>\nmaps out of gamut colors back into gamut.\n<br><br><a href=https://github.com/jedypod/gamut-compress>Documentation</a>"}
addUserKnob {20 doc_grp l "" +STARTLINE n 1}
doc_grp 0
addUserKnob {26 doc_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\n<b>Method</b><br>\nSpecify the tone compression curve to use when <br>\nmapping out of gamut colors into the boundary threshold.<br>\n<a href=https://www.desmos.com/calculator/hmzirlw7tj>log</a>\n<a href=https://www.desmos.com/calculator/lkhdtjbodx>reinhard</a>\n<a href=https://www.desmos.com/calculator/s2adnicmmr>exp</a>\n<a href=https://www.desmos.com/calculator/h96qmnozpo>atan</a>\n<a href=https://www.desmos.com/calculator/xiwliws24x>tanh</a>\n<br><br>\nThese curves are sorted by slope. Log is less steep and doesn't get as flat,<br>\nwhich results in more desaturation in compressed colors <br>\nat the same threshold. Tanh is more steep and gets flatter sooner<br>\nwhich causes colors to be more saturated at the same threshold. <br>\nYou may need to boost the threshold to get the desired color appearance with tanh.<br><br>\n\n<b>Threshold</b><br>\nPercentage of the gamut to affect. If threshold is 0.2, <br>\nthe inner 80% of the gamut will be unaffected and <br>\nout of gamut values will be compressed into <br>\nthe outer 20% of the gamut's color volume.<br><br>\n\n<b>Shadow Rolloff</b><br>\nReduce gamut compression in dark areas below specified value.<br>\nHelps reduce invertability issues in negative values from grain.<br><br>\n\n<b>Max Distance</b><br>\nPer color component control to specify what distance will be <br>\ncompressed to the gamut boundary. For example, <br>\na value of cyan=0.2 will map colors with a distance of red=1.2 from <br>\nthe achromatic axis to red=1.0, which is the gamut boundary.<br><br>\n\n<b>Calculate Max Distance</b><br>\nA helper to calculate the max distance that might occur when <br>\nmapping from a particular source color gamut. For example <br>\nwhen mapping from AlexaWideGamut to ACEScg, the max distance<br>\nof magenta will be highest and the other two components will be lower.<br>\nSetting these distance values according to the likely distances in the <br>\nsource gamut helps avoid unwanted shifts in color. The default is set to<br>\na good average among many digital cinema camera gamuts, but you may<br>\nwant to tweak these values for your needs.<br><br>\n<b>Direction</b><br>\nSpecifies whether to apply or inverse the gamut compression operation.<br><br>"}
addUserKnob {20 endGroup n -1}
addUserKnob {26 about_label l " " T "<style> a:link \{ color: #ccc \}</style>\n<font color=#ccc>\nWritten by <a href=https://github.com/jedypod color=red>Jed Smith</a> with <a href=https://community.acescentral.com/t/rgb-saturation-gamut-mapping-approach-and-a-comp-vfx-perspective>help</a> from the <a href=https://community.acescentral.com/c/aces-development-acesnext/vwg-aces-gamut-mapping-working-group>ACES Gamut Mapping VWG</a>"}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot4
xpos -6
ypos -174
}
set N9a680380 [stack 0]
Dot {
name Dot2
xpos -226
ypos -174
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -260
ypos -129
}
set Ned65fb50 [stack 0]
Dot {
name Dot1
xpos -226
ypos -78
}
set N96c5040 [stack 0]
Dot {
name Dot3
xpos -226
ypos 114
}
push $N96c5040
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -81
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
set N93980610 [stack 0]
Dot {
name Dot7
xpos -116
ypos 66
}
push $Ned65fb50
push $N9a680380
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge1
xpos -40
ypos -129
}
push $N93980610
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -81
}
Group {
name compress
knobChanged "from math import (pow, exp, log, tan, atan, atanh, cos, pi, fabs)\n\ndef i_log(x):\n return (exp((1-t+t*log(1-x)-x*t*log(1-x))/(t*(1-x))))*t+x*t-k\ndef i_exp(x):\n return -log((-x+1)/(t-x))*(-t+x)+t-k\ndef i_atan(x):\n return (2*tan((pi*(1-t))/(2*(x-t)))*(x-t))/pi+t-k\ndef i_tanh(x):\n return atanh((1-t)/(x-t))*(x-t)+t-k\ndef sign(x):\n return 0 if x == 0 else 1 if x > 0 else -1\n\ndef bisect(f, a, b):\n if sign(f(a)) == sign(f(b)): \n # bad estimate. return something close to linear\n if method == 'exp' or method == 'log':\n return -100\n else: \n return 1.99999\n c = (a+b)/2.0\n y = f(c)\n if fabs(y) <= tol:\n return c # lucky guess\n n = 1\n while fabs(y) > tol and n <= nmax:\n if sign(y) == sign(f(a)):\n a = c\n else:\n b = c\n c = (a+b)/2.0\n y = f(c)\n n += 1\n return c\n\ndef calc():\n a = 1.0001\n b = 5\n if method == 'log':\n f = i_log\n a = -50\n b = 0.98\n elif method == 'exp':\n f = i_exp\n elif method == 'atan':\n f = i_atan\n elif method == 'tanh':\n f = i_tanh\n a = 1.000001\n lim = bisect(f, a, b)\n return lim\n\nn = nuke.thisNode()\nknob = nuke.thisKnob()\n\nn.begin()\nif n\['method'].value() != 'reinhard':\n tol = 1e-3\n nmax = 100\n \n tk = n\['threshold']\n if tk.singleValue():\n thr = \[1-tk.getValue()]*3\n else:\n thr = \[1-v for v in tk.getValue()]\n\n method = n\['method'].value()\n\n k_knobs = \['cyan', 'magenta', 'yellow']\n lim_knobs = \['lim_x', 'lim_y', 'lim_z']\n if knob.name() in k_knobs:\n i = k_knobs.index(knob.name())\n lim_knob = lim_knobs\[i]\n t = thr\[i]\n k = knob.getValue()+1\n lim = calc()\n n\[lim_knob].setValue(lim)\n elif knob.name() == 'method' or knob.name() == 'threshold':\n for i, lknob in enumerate(lim_knobs):\n k = n\[k_knobs\[i]].getValue()+1\n t = thr\[i]\n lim = calc()\n n\[lknob].setValue(lim)\nn.end()"
xpos -40
ypos -25
addUserKnob {20 compress}
addUserKnob {4 method M {log reinhard exp atan tanh ""}}
method tanh
addUserKnob {18 threshold}
threshold 0.2
addUserKnob {6 threshold_panelDropped l "panel dropped state" -STARTLINE +HIDDEN}
addUserKnob {7 cyan}
cyan 0.2
addUserKnob {7 magenta}
magenta 0.2
addUserKnob {7 yellow}
yellow 0.2
addUserKnob {26 ""}
addUserKnob {7 lim_x R -5 2}
lim_x 1.00879006
addUserKnob {7 lim_y R -5 2}
lim_y 1.00879006
addUserKnob {7 lim_z R -5 2}
lim_z 1.00879006
addUserKnob {26 ""}
addUserKnob {6 invert +STARTLINE}
invert {{parent.direction}}
}
Input {
inputs 0
name Input
xpos -40
ypos -202
}
Dot {
name Dot2
xpos -6
ypos -102
}
set Nacf87340 [stack 0]
Dot {
name Dot1
xpos 324
ypos -30
}
set Nb6634b50 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*log((1+(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x)))/(1-(r/(lim_x-thr_x)-thr_x/(lim_x-thr_x))))/2
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*log((1+(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y)))/(1-(g/(lim_y-thr_y)-thr_y/(lim_y-thr_y))))/2
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*log((1+(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z)))/(1-(b/(lim_z-thr_z)-thr_z/(lim_z-thr_z))))/2
name uncompress_tanh
xpos 510
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Nb6634b50
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*tan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*tan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*tan(pi/2*(b-thr_z)/(lim_z-thr_z))
name uncompress_atan
xpos 400
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Nb6634b50
Expression {
expr0 r<thr_x?r:-log((r-lim_x)/(thr_x-lim_x))*(-thr_x+lim_x)+thr_x
expr1 g<thr_y?g:-log((g-lim_y)/(thr_y-lim_y))*(-thr_y+lim_y)+thr_y
expr2 b<thr_z?b:-log((b-lim_z)/(thr_z-lim_z))*(-thr_z+lim_z)+thr_z
name uncompress_exp
xpos 290
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $Nb6634b50
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)-1/(1-thr_x)+1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)-1/(1-thr_y)+1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)-1/(1-thr_z)+1/(lim_z-thr_z)))
name uncompress_reinhard
xpos 180
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.compress_reinhard.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.compress_reinhard.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.compress_reinhard.lim_z}}
}
push $Nb6634b50
Expression {
expr0 r<thr_x?r:exp((r-thr_x+thr_x*log(1-lim_x)-lim_x*thr_x*log(1-lim_x))/(thr_x*(1-lim_x)))*thr_x+lim_x*thr_x
expr1 "g<thr_y?g:exp((g-thr_y+thr_y*log(1-lim_y)-lim_y*thr_y*log(1-lim_y))/(thr_y*(1-lim_y)))*thr_y+lim_y*thr_y\n"
expr2 b<thr_z?b:exp((b-thr_z+thr_z*log(1-lim_z)-lim_z*thr_z*log(1-lim_z))/(thr_z*(1-lim_z)))*thr_z+lim_z*thr_z
name uncompress_log
xpos 70
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method1
xpos 290
ypos 135
}
push $Nacf87340
Dot {
name Dot6
xpos -336
ypos -30
}
set N3d141490 [stack 0]
Expression {
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*tanh(((r-thr_x)/(lim_x-thr_x)))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*tanh(((g-thr_y)/(lim_y-thr_y)))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*tanh(((b-thr_z)/(lim_z-thr_z)))
name compress_tanh
xpos -150
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N3d141490
Expression {
temp_name0 pi
temp_expr0 3.14159265359
expr0 r<thr_x?r:thr_x+(lim_x-thr_x)*2/pi*atan(pi/2*(r-thr_x)/(lim_x-thr_x))
expr1 g<thr_y?g:thr_y+(lim_y-thr_y)*2/pi*atan(pi/2*(g-thr_y)/(lim_y-thr_y))
expr2 b<thr_z?b:thr_z+(lim_z-thr_z)*2/pi*atan(pi/2*(b-thr_z)/(lim_z-thr_z))
name compress_atan
xpos -260
ypos 38
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N3d141490
Expression {
expr0 r<thr_x?r:lim_x-(lim_x-thr_x)*exp(-(((r-thr_x)*((lim_x)/(lim_x-thr_x))/lim_x)))
expr1 g<thr_y?g:lim_y-(lim_y-thr_y)*exp(-(((g-thr_y)*((lim_y)/(lim_y-thr_y))/lim_y)))
expr2 b<thr_z?b:lim_z-(lim_z-thr_z)*exp(-(((b-thr_z)*((lim_z)/(lim_z-thr_z))/lim_z)))
name compress_exp
xpos -370
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
push $N3d141490
Expression {
expr0 r<thr_x?r:(thr_x+1/(1/(r-thr_x)+1/(1-thr_x)-1/(lim_x-thr_x)))
expr1 g<thr_y?g:(thr_y+1/(1/(g-thr_y)+1/(1-thr_y)-1/(lim_y-thr_y)))
expr2 b<thr_z?b:(thr_z+1/(1/(b-thr_z)+1/(1-thr_z)-1/(lim_z-thr_z)))
name compress_reinhard
xpos -480
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.cyan+1}}
addUserKnob {7 lim_y}
lim_y {{parent.magenta+1}}
addUserKnob {7 lim_z}
lim_z {{parent.yellow+1}}
}
push $N3d141490
Expression {
expr0 r<thr_x?r:thr_x*log(r/thr_x-lim_x)-lim_x*thr_x*log(r/thr_x-lim_x)+thr_x-thr_x*log(1-lim_x)+lim_x*thr_x*log(1-lim_x)
expr1 g<thr_y?g:thr_y*log(g/thr_y-lim_y)-lim_y*thr_y*log(g/thr_y-lim_y)+thr_y-thr_y*log(1-lim_y)+lim_y*thr_y*log(1-lim_y)
expr2 b<thr_z?b:thr_z*log(b/thr_z-lim_z)-lim_z*thr_z*log(b/thr_z-lim_z)+thr_z-thr_z*log(1-lim_z)+lim_z*thr_z*log(1-lim_z)
name compress_log
xpos -590
ypos 39
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr_x}
thr_x {{1-parent.threshold.r}}
addUserKnob {7 thr_y}
thr_y {{1-parent.threshold.g}}
addUserKnob {7 thr_z}
thr_z {{1-parent.threshold.b}}
addUserKnob {7 lim_x}
lim_x {{parent.lim_x}}
addUserKnob {7 lim_y}
lim_y {{parent.lim_y}}
addUserKnob {7 lim_z}
lim_z {{parent.lim_z}}
}
Switch {
inputs 5
which {{parent.method}}
name switch_method
xpos -370
ypos 135
}
Switch {
inputs 2
which {{parent.invert}}
name switch_reverse
xpos -40
ypos 278
}
Output {
name Output
xpos -40
ypos 422
}
end_group
Merge2 {
inputs 2
operation multiply
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos 63
}
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge5
xpos -40
ypos 111
}
Output {
name Output
xpos -40
ypos 182
}
push $N9a680380
Group {
inputs 0
name RGB
xpos 180
ypos -274
}
Constant {
inputs 0
color {0 0 0 0}
format "4 1 0 0 4 1 1 rgbw"
name Constant3
note_font "Bitstream Vera Sans"
xpos 510
ypos -34
postage_stamp false
}
Reformat {
type "to box"
box_width 3
box_height 2
box_fixed true
name Reformat1
xpos 510
ypos -10
}
Rectangle {
area {0 0 1 2}
color {1 0 0 0}
name Rectangle1
note_font "Bitstream Vera Sans"
xpos 510
ypos 14
}
Rectangle {
area {1 0 2 2}
color {0 1 0 0}
name Rectangle2
note_font "Bitstream Vera Sans"
xpos 510
ypos 38
}
Rectangle {
area {2 0 3 2}
color {0 0 1 0}
name Rectangle3
note_font "Bitstream Vera Sans"
xpos 510
ypos 62
}
Output {
name Output
xpos 510
ypos 110
}
end_group
Group {
name Gamut
xpos 180
ypos -226
addUserKnob {20 GamutToXYZ_tab l GamutToXYZ}
addUserKnob {4 gamut_in l "gamut in" t "Choose source gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_in ACEScg
addUserKnob {4 gamut_out l "gamut out" t "Choose destination gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_out "Arri AlexaWideGamut"
addUserKnob {6 invert +STARTLINE}
invert true
}
Input {
inputs 0
name Input
xpos -40
ypos -130
}
Dot {
name Dot1
xpos -6
ypos -78
}
set N93c8b8f0 [stack 0]
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name ColorMatrix2
label "RGB to XYZ"
xpos 180
ypos 32
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9872239828 -0.006113247015 0.01595330238}
{-0.007598329335 1.001861453 0.005330037326}
{0.00307257846 -0.00509596616 1.081680536}
}
invert {{!parent.ColorMatrix4.invert}}
name ColorMatrix1
label "CAT: Bradford\n ACES to D65"
xpos 180
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name ColorMatrix3
label "XYZ to RGB"
xpos 180
ypos 176
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
push $N93c8b8f0
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name RGBtoXYZ
xpos -260
ypos 38
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9874471426 -0.005980737507 0.01595583558}
{-0.00739388587 1.001675606 0.005319938064}
{0.003088310361 -0.005131930113 1.081959367}
}
invert {{"parent.RGBtoXYZ.wxy == 0.3127"}}
name ColorMatrix4
label "CAT: Bradford\n D60 to D65"
xpos -260
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name XYZtoRGB
xpos -260
ypos 182
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
Switch {
inputs 2
which {{parent.invert}}
name switch_direction
xpos -40
ypos 303
}
Output {
name Output
xpos -40
ypos 374
}
push $N93c8b8f0
ColorMatrix {
matrix {
{{curve 0.9525524378 0.6624541879 0.7053968906 0.4123907983 0.6369580626 0.5049495697 0.4865709841 0.6380076408 0.7352752686 0.5022571683 0.7160496712 0.7064827085 0.5990839601 0.6796444654 0.6481720209 0.6065810919 0.7165006995 0.7976718545} {curve 0 0.1340042055 0.1640413404 0.3575843275 0.1446169019 0.2646814585 0.2656676769 0.2147038579 0.06860940903 0.2929667532 0.1296834797 0.1288010478 0.2489254922 0.1522114277 0.1940581352 0.2203479856 0.1010205746 0.1351878047} {curve 9.367863095e-05 0.1561876982 0.08101774752 0.180480808 0.1688809693 0.1830150485 0.1982172877 0.09774444997 0.1465712637 0.1552320272 0.1047228053 0.1151721701 0.1024464965 0.1186000481 0.108225815 0.123526901 0.1467743814 0.03133957833}}
{{curve 0.3439664543 0.2722287476 0.2801307142 0.2126390189 0.2627002299 0.237623319 0.2289745659 0.2919537723 0.2866941094 0.1387997568 0.2612613738 0.2709796727 0.2150758505 0.2606855333 0.2830046713 0.2680045366 0.258728236 0.2880405784} {curve 0.7281661034 0.6740817428 0.8202066422 0.7151686549 0.6779980659 0.6891706586 0.6917385459 0.8238410354 0.8429791331 0.910841465 0.8696421385 0.786606431 0.8850684762 0.7748944759 0.8131960034 0.8326833844 0.7246823311 0.7118694782} {curve -0.07213255018 0.05368951708 -0.1003373638 0.07219231874 0.05930171534 0.07320601493 0.07928691059 -0.1157948226 -0.1296732277 -0.04964122549 -0.1309035122 -0.05758608505 -0.1001443192 -0.03558001295 -0.09620071948 -0.1006879359 0.01658944227 8.991353388e-05}}
{{curve -3.863927134e-08 -0.005574660841 -0.1037815213 0.01933082007 0 0 0 0.0027982709 -0.07968087494 0.07801423222 -0.009676366113 -0.009677864611 -0.03206583485 -0.009310216643 -0.01825834997 -0.02941203304 -2.906408625e-08 0} {curve 0 0.004060741514 -0.07290724665 0.1191947311 0.0280726999 0.0449459292 0.04511339962 -0.06703422964 -0.3473432064 -0.3148325086 -0.2364816219 0.004600019194 -0.02765839547 -0.004612449091 -0.08316776901 -0.08659287542 0.05121183768 -1.262213711e-08} {curve 1.008825183 1.010339141 1.265746474 0.950532198 1.060985088 0.9638792276 1.043944359 1.153293729 1.51608181 1.325875998 1.335215807 1.094135642 1.148782015 1.102980375 1.190483928 1.205062628 0.7738927603 0.8248898983}}
}
name mtx
label "\n"
xpos -40
ypos 38
addUserKnob {20 Params}
addUserKnob {12 rxy}
rxy {{curve 0.7347 0.713 0.8 0.64 0.708 0.68 0.68 0.684 0.780308 0.69848046 0.74 0.73 0.766 0.73 0.71 0.7177 0.7347 0.734699} {curve 0.2653 0.293 0.3177 0.33 0.292 0.32 0.32 0.313 0.304253 0.19302645 0.27 0.28 0.275 0.28 0.31 0.3171 0.2653 0.265301}}
addUserKnob {12 gxy}
gxy {{curve 0 0.165 0.18 0.3 0.17 0.265 0.265 0.221 0.121595 0.32955538 0.17 0.14 0.225 0.165 0.21 0.228 0.1152 0.159597} {curve 1 0.83 0.9 0.6 0.797 0.69 0.69 0.848 1.493994 1.02459662 1.14 0.855 0.8 0.84 0.88 0.8616 0.8264 0.840403}}
addUserKnob {12 bxy}
bxy {{curve 0.0001 0.128 0.065 0.15 0.131 0.15 0.15 0.0861 0.095612 0.10844263 0.08 0.1 0.089 0.1 0.09 0.1006 0.1566 0.036598} {curve -0.077 0.044 -0.0805 0.06 0.046 0.06 0.06 -0.102 -0.084589 -0.03467857 -0.1 -0.05 -0.087 -0.03 -0.08 -0.082 0.0177 0.000105}}
addUserKnob {12 wxy}
wxy {{curve 0.32168 0.32168 0.3127 0.3127 0.3127 0.32168 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3457 0.345704} {curve 0.33767 0.33767 0.329 0.329 0.329 0.33767 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.3585 0.35854}}
}
end_group
Switch {
inputs 2
which {{parent.use_input_image}}
name Switch_distance_source
xpos 180
ypos -177
}
Group {
name ColorDistance
xpos 180
ypos -130
addUserKnob {20 ColorDistance}
addUserKnob {7 shd_rolloff l "shd rolloff" R 0 0.1}
shd_rolloff {{parent.shd_rolloff}}
}
Input {
inputs 0
name Input
xpos -40
ypos -274
}
Dot {
name Dot5
xpos -6
ypos -222
}
set N17b13030 [stack 0]
Dot {
name Dot1
xpos -116
ypos -222
}
Expression {
channel0 {rgba.red rgba.green rgba.blue none}
expr0 max(r,g,b)
name achromatic
xpos -150
ypos -177
}
set N1c12c980 [stack 0]
push $N17b13030
Merge2 {
inputs 2
operation minus
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge2
xpos -40
ypos -177
}
push $N1c12c980
Expression {
temp_name0 c_r
temp_expr0 1-r
temp_name1 c_g
temp_expr1 1-g
temp_name2 c_b
temp_expr2 1-b
expr0 1-(c_r<(1-thr)?c_r:(1-thr)+thr*tanh(((c_r-(1-thr))/thr)))
expr1 1-(c_g<(1-thr)?c_g:(1-thr)+thr*tanh(((c_g-(1-thr))/thr)))
expr2 1-(c_b<(1-thr)?c_b:(1-thr)+thr*tanh(((c_b-(1-thr))/thr)))
name toe
xpos -150
ypos -129
disable {{parent.shd_rolloff==0}}
addUserKnob {20 Params_tab l Params}
addUserKnob {7 thr t "complement of threshold"}
thr {{parent.shd_rolloff}}
}
Merge2 {
inputs 2
operation divide
bbox B
Achannels rgb
Bchannels rgb
output rgb
name Merge3
xpos -40
ypos -129
}
Output {
name Output
xpos -40
ypos -58
}
end_group
CurveTool {
operation "Max Luma Pixel"
channels {rgba.red -rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve} {curve}}
maxlumapixvalue {{curve} {curve} 0}
minlumapixdata {{curve} {curve}}
minlumapixvalue {{curve} {curve} 0}
name RMAX
tile_color 0x84000000
xpos 180
ypos -81
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red rgba.green -rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x1 2} {curve x1 0}}
maxlumapixvalue {{curve x1 0} {curve x1 1.218766689} 0}
minlumapixdata {{curve x1 1} {curve x1 0}}
minlumapixvalue {{curve x1 0} {curve x1 0} 0}
name GMAX
tile_color 0x84000000
xpos 180
ypos -57
}
CurveTool {
operation "Max Luma Pixel"
channels {-rgba.red -rgba.green rgba.blue none}
ROI {0 0 {width} {height}}
autocropdata {480 270 1440 810}
maxlumapixdata {{curve x1 1} {curve x1 0}}
maxlumapixvalue {{curve x1 0} {curve x1 0} 1.052656531}
minlumapixdata {{curve x1 2} {curve x1 0}}
minlumapixvalue {{curve x1 0} {curve x1 0} 0}
name BMAX
tile_color 0x84000000
xpos 180
ypos -33
}
end_group
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "tanh: thr 0.2 lim 0.2"
old_message {{116 97 110 104 58 32 116 104 114 32 48 46 50 32 108 105 109 32 48 46 50}
}
box {2.25 -0.625 229.75 41.625}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 11 24 12 24 13 24 14 24 15 24 16 24 17 24 18 24 19 24 20 24 0 50}
}
cursor_position 21
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text1
note_font Helvetica
selected true
xpos 8540
ypos 8458
}
push $N51f0100
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "aces rec709"
old_message {{97 99 101 115 32 114 101 99 55 48 57}
}
box {298.75 0.875 526.25 43.125}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 0 50}
}
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text6
note_font Helvetica
selected true
xpos 8424
ypos 8415
}
Switch {
inputs 4
which {{t-1}}
name Switch5
note_font Helvetica
selected true
xpos 8650
ypos 8527
}
Text2 {
font_size_toolbar 24
font_width_toolbar 100
font_height_toolbar 100
message "aces rec709"
old_message {{97 99 101 115 32 114 101 99 55 48 57}
}
box {298.75 0.875 526.25 43.125}
yjustify bottom
transforms {{0 2}
}
font_size_values {{0 24 1 24 2 24 3 24 4 24 5 24 6 24 7 24 8 24 9 24 10 24 0 50}
}
font_size 24
center {217 97}
cursor_initialised true
autofit_bbox false
initial_cursor_position {{1 41.25}
}
group_animations {{0} imported: 0 selected: items: "root transform/"}
animation_layers {{1 11 217 97 0 0 1 1 0 0 0 0}
}
color {1 1 1 1}
enable_background true
background_opacity 0.965
background_border_x 7.7
background_border_y 1.8
shadow_opacity 1
shadow_distance 0.8
shadow_softness 3.95
name Text4
note_font Helvetica
selected true
xpos 8650
ypos 8583
}
Group {
name Gamut2
label "\[if \{\[value invert]\} \{return \"\[value gamut_out] to \[value gamut_in]\"\} else \{return \"\[value gamut_in] to \[value gamut_out]\"\}]"
selected true
xpos 8650
ypos 8624
addUserKnob {20 GamutToXYZ_tab l GamutToXYZ}
addUserKnob {4 gamut_in l "gamut in" t "Choose source gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
addUserKnob {4 gamut_out l "gamut out" t "Choose destination gamut" M {ACES ACEScg "Filmlight E-Gamut" Rec709 Rec2020 P3D60 P3D65 "Arri AlexaWideGamut" REDWideGamutRGB "GoPro Protune Native" CanonCinemaGamut SonySGamut SonySGamut3Cine PanasonicVGamut "DJI D-Gamut" BMDWideGamutGen4 AdobeWideGamutRGB ProPhotoRGB}}
gamut_out ACEScg
addUserKnob {6 invert +STARTLINE}
invert true
}
Input {
inputs 0
name Input
xpos -40
ypos -130
}
Dot {
name Dot1
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
xpos -6
ypos -78
}
set Nb2ba2810 [stack 0]
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name ColorMatrix2
label "RGB to XYZ"
xpos 180
ypos 32
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9872239828 -0.006113247015 0.01595330238}
{-0.007598329335 1.001861453 0.005330037326}
{0.00307257846 -0.00509596616 1.081680536}
}
invert {{!parent.ColorMatrix4.invert}}
name ColorMatrix1
label "CAT: Bradford\n ACES to D65"
note_font Helvetica
xpos 180
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name ColorMatrix3
label "XYZ to RGB"
xpos 180
ypos 176
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
push $Nb2ba2810
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
name RGBtoXYZ
xpos -260
ypos 38
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_in}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
ColorMatrix {
matrix {
{0.9874471426 -0.005980737507 0.01595583558}
{-0.00739388587 1.001675606 0.005319938064}
{0.003088310361 -0.005131930113 1.081959367}
}
invert {{"parent.RGBtoXYZ.wxy == 0.3127"}}
name ColorMatrix4
label "CAT: Bradford\n D60 to D65"
note_font Helvetica
xpos -260
ypos 101
disable {{"RGBtoXYZ.wxy == XYZtoRGB.wxy"}}
}
ColorMatrix {
matrix {
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
{{parent.mtx.matrix(which)} {parent.mtx.matrix(which)} {parent.mtx.matrix(which)}}
}
invert true
name XYZtoRGB
xpos -260
ypos 182
addUserKnob {20 Gamut}
addUserKnob {3 which}
which {{parent.gamut_out}}
addUserKnob {12 rxy}
rxy {{parent.mtx.rxy(which)} {parent.mtx.rxy(which)}}
addUserKnob {12 gxy}
gxy {{parent.mtx.gxy(which)} {parent.mtx.gxy(which)}}
addUserKnob {12 bxy}
bxy {{parent.mtx.bxy(which)} {parent.mtx.bxy(which)}}
addUserKnob {12 wxy}
wxy {{parent.mtx.wxy(which)} {parent.mtx.wxy(which)}}
}
Switch {
inputs 2
which {{parent.invert}}
name switch_direction
note_font Helvetica
xpos -40
ypos 303
}
Output {
name Output
xpos -40
ypos 374
}
push $Nb2ba2810
ColorMatrix {
matrix {
{{curve 0.9525524378 0.6624541879 0.7053968906 0.4123907983 0.6369580626 0.5049495697 0.4865709841 0.6380076408 0.7352752686 0.5022571683 0.7160496712 0.7064827085 0.5990839601 0.6796444654 0.6481720209 0.6065810919 0.7165006995 0.7976718545} {curve 0 0.1340042055 0.1640413404 0.3575843275 0.1446169019 0.2646814585 0.2656676769 0.2147038579 0.06860940903 0.2929667532 0.1296834797 0.1288010478 0.2489254922 0.1522114277 0.1940581352 0.2203479856 0.1010205746 0.1351878047} {curve 9.367863095e-05 0.1561876982 0.08101774752 0.180480808 0.1688809693 0.1830150485 0.1982172877 0.09774444997 0.1465712637 0.1552320272 0.1047228053 0.1151721701 0.1024464965 0.1186000481 0.108225815 0.123526901 0.1467743814 0.03133957833}}
{{curve 0.3439664543 0.2722287476 0.2801307142 0.2126390189 0.2627002299 0.237623319 0.2289745659 0.2919537723 0.2866941094 0.1387997568 0.2612613738 0.2709796727 0.2150758505 0.2606855333 0.2830046713 0.2680045366 0.258728236 0.2880405784} {curve 0.7281661034 0.6740817428 0.8202066422 0.7151686549 0.6779980659 0.6891706586 0.6917385459 0.8238410354 0.8429791331 0.910841465 0.8696421385 0.786606431 0.8850684762 0.7748944759 0.8131960034 0.8326833844 0.7246823311 0.7118694782} {curve -0.07213255018 0.05368951708 -0.1003373638 0.07219231874 0.05930171534 0.07320601493 0.07928691059 -0.1157948226 -0.1296732277 -0.04964122549 -0.1309035122 -0.05758608505 -0.1001443192 -0.03558001295 -0.09620071948 -0.1006879359 0.01658944227 8.991353388e-05}}
{{curve -3.863927134e-08 -0.005574660841 -0.1037815213 0.01933082007 0 0 0 0.0027982709 -0.07968087494 0.07801423222 -0.009676366113 -0.009677864611 -0.03206583485 -0.009310216643 -0.01825834997 -0.02941203304 -2.906408625e-08 0} {curve 0 0.004060741514 -0.07290724665 0.1191947311 0.0280726999 0.0449459292 0.04511339962 -0.06703422964 -0.3473432064 -0.3148325086 -0.2364816219 0.004600019194 -0.02765839547 -0.004612449091 -0.08316776901 -0.08659287542 0.05121183768 -1.262213711e-08} {curve 1.008825183 1.010339141 1.265746474 0.950532198 1.060985088 0.9638792276 1.043944359 1.153293729 1.51608181 1.325875998 1.335215807 1.094135642 1.148782015 1.102980375 1.190483928 1.205062628 0.7738927603 0.8248898983}}
}
name mtx
label "\n"
xpos -40
ypos 38
addUserKnob {20 Params}
addUserKnob {12 rxy}
rxy {{curve 0.7347 0.713 0.8 0.64 0.708 0.68 0.68 0.684 0.780308 0.69848046 0.74 0.73 0.766 0.73 0.71 0.7177 0.7347 0.734699} {curve 0.2653 0.293 0.3177 0.33 0.292 0.32 0.32 0.313 0.304253 0.19302645 0.27 0.28 0.275 0.28 0.31 0.3171 0.2653 0.265301}}
addUserKnob {12 gxy}
gxy {{curve 0 0.165 0.18 0.3 0.17 0.265 0.265 0.221 0.121595 0.32955538 0.17 0.14 0.225 0.165 0.21 0.228 0.1152 0.159597} {curve 1 0.83 0.9 0.6 0.797 0.69 0.69 0.848 1.493994 1.02459662 1.14 0.855 0.8 0.84 0.88 0.8616 0.8264 0.840403}}
addUserKnob {12 bxy}
bxy {{curve 0.0001 0.128 0.065 0.15 0.131 0.15 0.15 0.0861 0.095612 0.10844263 0.08 0.1 0.089 0.1 0.09 0.1006 0.1566 0.036598} {curve -0.077 0.044 -0.0805 0.06 0.046 0.06 0.06 -0.102 -0.084589 -0.03467857 -0.1 -0.05 -0.087 -0.03 -0.08 -0.082 0.0177 0.000105}}
addUserKnob {12 wxy}
wxy {{curve 0.32168 0.32168 0.3127 0.3127 0.3127 0.32168 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3127 0.3457 0.345704} {curve 0.33767 0.33767 0.329 0.329 0.329 0.33767 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.329 0.3585 0.35854}}
}
end_group
Group {
name ACES_OutputTransform
tile_color 0xa57aaaff
label Rec.709
selected true
xpos 8650
ypos 8672
addUserKnob {20 ACES_OutputTransform_tab l "ACES OutputTransform"}
addUserKnob {35 presets t "display output presets." M {display/sRGB "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 0 limiting_pri 0 eotf 0 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 1 legal_range 0 label \"sRGB\"\}" "display/sRGB D60 sim." "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 0 limiting_pri 0 eotf 0 stretch_black 0 d60_sim 1 force_d65_cat 0 dark_to_dim 1 legal_range 0 label \"sRGB D60 sim.\"\}" display/Rec.709 "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 0 limiting_pri 0 eotf 1 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 1 legal_range 0 label \"Rec.709\"\}" "display/Rec.709 D60 sim." "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 0 limiting_pri 0 eotf 1 stretch_black 0 d60_sim 1 force_d65_cat 0 dark_to_dim 1 legal_range 0 label \"Rec.709 D60 sim.\"\}" display/Rec.2020 "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 1 limiting_pri 1 eotf 1 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 1 legal_range 0 label \"Rec.2020\"\}" display/P3D60 "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 4 limiting_pri 4 eotf 4 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D60\"\}" display/P3D65 "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 2 limiting_pri 2 eotf 4 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65\"\}" "display/P3D65 D60 sim." "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 2 limiting_pri 2 eotf 4 stretch_black 0 d60_sim 1 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 D60 sim.\"\}" display/P3DCI "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 3 limiting_pri 3 eotf 4 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3DCI\"\}" "display/P3DCI D60 sim." "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 3 limiting_pri 3 eotf 4 stretch_black 0 d60_sim 1 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3DCI D60 sim.\"\}" "display/P3DCI D65 sim." "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 3 limiting_pri 3 eotf 4 stretch_black 0 d60_sim 0 force_d65_cat 1 dark_to_dim 0 legal_range 0 label \"P3DCI D65 sim.\"\}" display/DCDM "knobs this \{lum \{0.02 4.8 48\} override_ssts_params 0 use_c9 1 display_pri 7 limiting_pri 7 eotf 5 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"DCDM\"\}" "display/P3D65 ST2084 108nits 7.2nits" "knobs this \{lum \{0.0001 7.2 108\} override_ssts_params 0 use_c9 0 display_pri 2 limiting_pri 2 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 ST2084 108nits 7.2nits\"\}" "display/P3D65 ST2084 1000nits 15nits" "knobs this \{lum \{0.0001 15 1000\} override_ssts_params 0 use_c9 0 display_pri 2 limiting_pri 2 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 ST2084 1000nits 15nits\"\}" "display/P3D65 ST2084 2000nits 15nits" "knobs this \{lum \{0.0001 15 2000\} override_ssts_params 0 use_c9 0 display_pri 2 limiting_pri 2 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 ST2084 2000nits 15nits\"\}" "display/P3D65 ST2084 2000nits 15nits" "knobs this \{lum \{0.0001 15 2000\} override_ssts_params 0 use_c9 0 display_pri 2 limiting_pri 2 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 ST2084 2000nits 15nits\"\}" "display/P3D65 ST2084 4000nits 15nits" "knobs this \{lum \{0.0001 15 4000\} override_ssts_params 0 use_c9 0 display_pri 2 limiting_pri 2 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"P3D65 ST2084 4000nits 15nits\"\}" display/Rec2020_HLG_1000nits_15nits "knobs this \{lum \{0.0001 15 1000\} override_ssts_params 0 use_c9 0 display_pri 1 limiting_pri 1 eotf 7 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"Rec2020_HLG_1000nits_15nits\"\}" display/Rec2020_ST2084_1000nits_15nits "knobs this \{lum \{0.0001 15 1000\} override_ssts_params 0 use_c9 0 display_pri 1 limiting_pri 1 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"Rec2020_ST2084_1000nits_15nits\"\}" display/Rec2020_ST2084_2000nits_15nits "knobs this \{lum \{0.0001 15 2000\} override_ssts_params 0 use_c9 0 display_pri 1 limiting_pri 1 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"Rec2020_ST2084_2000nits_15nits\"\}" display/Rec2020_ST2084_4000nits_15nits "knobs this \{lum \{0.0001 15 4000\} override_ssts_params 0 use_c9 0 display_pri 1 limiting_pri 1 eotf 6 stretch_black 1 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"Rec2020_ST2084_4000nits_15nits\"\}" display/OCES "knobs this \{lum \{0.0001 4.8 10000\} override_ssts_params 0 use_c9 0 display_pri 6 limiting_pri 6 eotf 9 stretch_black 0 d60_sim 0 force_d65_cat 0 dark_to_dim 0 legal_range 0 label \"OCES\"\}" "" ""}}
addUserKnob {26 ""}
addUserKnob {26 display_label l " " T "<b>Display Settings</b>"}
addUserKnob {78 lum l luminance t "<b>SSTS Display Luminance</b>: \ny_min y_mid y_max\n\nAccording to Zach Lewis's ACES_OT\nhttps://gist.github.com/zachlewis/786c0be941868644c993fde1c3515c2c\n\n<b>Standard Cinema</b>: \n0.02 4.8 48\n<b>Dolby Cinema</b>: \n0.0001 7.2 108\n<b>Dolby Pulsar</b>: \n0.005 15 4000\n<b>Dolby PRR-4220</b>: \n0.005 10 600\n<b>Sony BVM-X300</b>: \n0.0001 10 1000\n<b>ACES OCES</b>: \n0.0001 4.8 10000\n\n" n 3}
lum {0.02 4.8 48}
addUserKnob {20 ssts_params_grp l "SSTS Parameters" n 1}
ssts_params_grp 0
addUserKnob {6 override_ssts_params l "override ssts params" t "Enable overrides of SSTS params.\n\nOtherwise the values will be calculated automatically by the algorithm." +STARTLINE}
addUserKnob {35 presets_ssts_param l presets t "If you want to override the default SSTS parameters and play around, here are some useful starting points." M {contrast/default "knobs this \{override_ssts_params 0 pctLow 0.35 pctHigh 0.89 slope \{0 1.5 0.\} exposure 0.0 use_c9 0\}" contrast/sdr "knobs this \{override_ssts_params 1 pctLow 0.35 pctHigh 0.89 slope \{0.1 1.6 0.01\} exposure 0.0 use_c9 0\}" contrast/high "knobs this \{override_ssts_params 1 pctLow 0.2 pctHigh 0.89 slope \{0.28 1.75 0.01\} exposure 0.0 use_c9 0\}" contrast/med "knobs this \{override_ssts_params 1 pctLow 0.40 pctHigh 0.89 slope \{0.38 1.3 0.01\} exposure 0.0 use_c9 0\}" contrast/med-low "knobs this \{override_ssts_params 1 pctLow 0.40 pctHigh 0.80 slope \{0.38 1.42 0.01\} exposure 0.0 use_c9 0\}" contrast/low "knobs this \{override_ssts_params 1 pctLow 0.40 pctHigh 0.80 slope \{0.38 1.2 0.01\} exposure 0.0 use_c9 0\}" ""}}
addUserKnob {7 exposure R -5 5}
addUserKnob {7 pctLow l knee}
pctLow 0.35
addUserKnob {7 pctHigh l shoulder}
pctHigh 0.89
addUserKnob {78 slope n 3}
slope {0.38 1.501 0.01}
addUserKnob {20 endGroup n -1}
addUserKnob {6 use_c9 l "use SegmentedSpline_c9" t "In ACES 1.1 the Output Transform was re-written for HDR tonescales. \n\nIn ACES 1.1, HDR transforms use the new SSTS (Single Stage Tone Scale), while SDR transforms continue to use the old SegmentedSpline_c5 -> OCES -> SegmentedSpline_c9 -> ODT transform.\n\nIf this is enabled, the SegmentedSpline_c9 transform is used to maintain compatibility with the ACES SDR output transforms and enable a 1:1 match with the AMPAS CTL.\n\nIf you are curious, turn use_c9 off and play around with the SSTS Parameters." +STARTLINE}
use_c9 true
addUserKnob {26 ""}
addUserKnob {4 display_pri l "display pri" t "Display encoding primaries." M {Rec709 Rec2020 P3D65 P3DCI P3D60 ACEScg ACES XYZ}}
addUserKnob {4 limiting_pri l "limiting pri" t "Limiting primaries for the output transform." -STARTLINE M {Rec709 Rec2020 P3D65 P3DCI P3D60 ACEScg ACES XYZ}}
addUserKnob {4 eotf l EOTF t "Electrical to Optical Transfer Function of the monitor." M {sRGB BT.1886 "Gamma 2.2" "Gamma 2.4" "Gamma 2.6" DCDM "ST-2084 (PQ)" HLG Linear OCES ""}}
eotf BT.1886
addUserKnob {6 stretch_black l "stretch black" t "For hdr outputs: stretch black luminance to a PQ code value of 0" +STARTLINE}
addUserKnob {6 d60_sim l "d60 sim" t "d60 whitepoint simulation." +STARTLINE}
addUserKnob {6 force_d65_cat l "force d60 to d65 cat" -STARTLINE}
addUserKnob {6 dark_to_dim l "dark to dim surround" t "Apply gamma adjustment to compensate for \"Dark to Dim\" surround. For SDR outputs only." +STARTLINE}
dark_to_dim true
addUserKnob {6 legal_range l "legal range" t "Output legal range." +STARTLINE}
addUserKnob {26 ""}
addUserKnob {26 blinkscript_options_label l " " T <b>BlinkScript}
addUserKnob {6 use_gpu l "use gpu" t "Enable GPU processing for the blinkscript nodes" +STARTLINE}
use_gpu true
addUserKnob {6 vectorize t "Vectorize on the CPU for blinkscript nodes" -STARTLINE}
vectorize true
}
BackdropNode {
inputs 0
name Electrical_Optical_Transfer_Function
tile_color 0x151515ff
label "ACESlib.OutputTransforms.ctl : 185\n// EOTF"
note_font_size 12
xpos -2025
ypos 2294
bdwidth 3391
bdheight 740
z_order -10
}
BackdropNode {
inputs 0
name BackdropNode1
tile_color 0x272727ff
label "HDR EOTFs"
note_font_size 42
xpos 425
ypos 2379
bdwidth 910
bdheight 617
z_order -5
}
BackdropNode {
inputs 0
name BackdropNode2
tile_color 0x272727ff
label "SDR EOTFs"
note_font_size 42
xpos -1158
ypos 2384
bdwidth 1436
bdheight 608
z_order -5
}
BackdropNode {
inputs 0
name AP1_to_XYZ
tile_color 0x555b5cff
label "ACESlib.OutputTransforms.ctl : 90\n// Rendering primaries to XYZ\n"
note_font_size 12
xpos -1400
ypos 906
bdwidth 380
bdheight 156
}
BackdropNode {
inputs 0
name AP1_to_XYZ1
tile_color 0x555a5cff
label "// Apply desaturation to compensate for luminance difference\nlinearCV = mult_f3_f33( linearCV, ODT_SAT_MAT);\n( SDR only)"
note_font_size 12
xpos -1412
ypos 669
bdwidth 439
bdheight 186
}
BackdropNode {
inputs 0
name D60_whitepoint_simulation
tile_color 0x232323ff
label "ACESlib.OutputTransforms.ctl : 150\n// Scale to avoid clipping when device calibration is different from D60. \n// To simulate D60, unequal code values are sent to the display.\n"
note_font_size 12
xpos -1399
ypos 176
bdwidth 818
bdheight 463
}
BackdropNode {
inputs 0
name Luminance_to_Linear_Code_Values
tile_color 0x272727ff
label "ACESlib.OutputTransforms.ctl : 87\n/* Scale absolute luminance to linear code value */\n"
note_font_size 12
xpos -1367
ypos -50
bdwidth 315
bdheight 148
}
BackdropNode {
inputs 0
name Output_Color_Encoding_Specification
tile_color 0x1d1d1dff
label "<font size=12>OCES\n<font size=0.1>\n- ACES Output Output Color Encoding Specification \n- An idealized reference display with 0.0001 / 4.8 / 10000 luma\n w/ ACES AP0 Primaries."
note_font_size 27.4
xpos -1833
ypos 2379
bdwidth 367
bdheight 377
}
BackdropNode {
inputs 0
name Output_Legal_Range
tile_color 0x272727ff
label "ACESlib.OutputTransforms.ctl : 216\n"
note_font_size 12
xpos -1369
ypos 3128
bdwidth 318
bdheight 176
}
BackdropNode {
inputs 0
name Single_Stage_Tone_Scale
tile_color 0x272727ff
label "<b>Single Stage Tone Scale : ACESlib.OutputTransforms.ctl : 82</b><pre>// Apply the tonescale independently in rendering-space RGB\nfloat rgbPost\[3] = ssts_f3( rgbPre, PARAMS);\n\nIf output is SDR, output OCES from SSTS and use SegmentedSpline_c9."
note_font_size 12
xpos -1502
ypos -653
bdwidth 609
bdheight 533
}
BackdropNode {
inputs 0
name clamp_negatives
tile_color 0x272727ff
label "ACESlib.OutputTransforms.ctl : 174\n// Clip values < 0 (i.e. projecting outside the display primaries)\nNote: Also clamping values > 1 here."
note_font_size 12
xpos -1393
ypos 2087
bdwidth 386
bdheight 120
}
BackdropNode {
inputs 0
name dim_surround_gamma_adjustment
tile_color 0x272727ff
label "ACESlib.OutputTransforms.ctl : 92\n// Apply gamma adjustment to compensate for dim surround\n"
note_font_size 12
xpos -1407
ypos 1063
bdwidth 395
bdheight 258
}
BackdropNode {
inputs 0
name limit_primaries
tile_color 0x555a5cff
label "ACESlib.OutputTransforms.ctl : 130\n// Gamut limit to limiting primaries\n"
note_font_size 12
xpos -1408
ypos 1655
bdwidth 396
bdheight 194
}
BackdropNode {
inputs 0
name limit_primaries1
tile_color 0x555a5cff
label "ACESlib.OutputTransforms.ctl : 144\n// CIE XYZ to display encoding primaries\n"
note_font_size 12
xpos -1402
ypos 1892
bdwidth 384
bdheight 151
}
BackdropNode {
inputs 0
name limit_primaries2
tile_color 0x555a5cff
label "ACESlib.OutputTransforms.ctl : 130\n // Apply CAT from ACES white point to assumed observer adapted white point\n // TODO: Needs to expand from just supporting D60 sim to allow for any\n // observer adapted white point.\n"
note_font_size 12
xpos -1407
ypos 1337
bdwidth 467
bdheight 301
}
BackdropNode {
inputs 0
name rrt_sweeteners_
tile_color 0x555a5cff
label "<b>RRT Sweeteners : ACESlib.OutputTransforms.ctl : 79</b><pre>// RRT sweeteners\nfloat rgbPre\[3] = rrt_sweeteners( in);\n"
note_font_size 18
xpos -1469
ypos -1234
bdwidth 519
bdheight 548
}
Input {
inputs 0
name Input
xpos -1250
ypos -1450
}
AddChannels {
channels rgba
name AddChannels
xpos -1250
ypos -1378
}
Dot {
name Dot7
label " ACES 2065-1 IN"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos -1302
}
BlinkScript {
recompileCount 87
ProgramGroup 1
KernelDescription "2 \"ACES_rrt_sweetener_glow_module\" iterate pixelWise 75f48b280734753b8fc802d2ab2e3ba5f31e66e541fc1473537319fbfb99939c 2 \"src\" Read Point \"dst\" Write Point 3 \"RRT_GLOW_GAIN\" Float 1 AAAAAA== \"RRT_GLOW_MID\" Float 1 AAAAAA== \"invert\" Bool 1 AA== 3 \"RRT_GLOW_GAIN\" 1 1 \"RRT_GLOW_MID\" 1 1 \"invert\" 1 1 0"
kernelSource "kernel ACES_rrt_sweetener_glow_module : public ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\nparam:\n // User controllable parameters\n float RRT_GLOW_GAIN;\n float RRT_GLOW_MID;\n bool invert;\n // \"Glow\" module constants\n // RRT_GLOW_GAIN = 0.05;\n // RRT_GLOW_MID = 0.08;\n\n\n float3 mult_f_f3( float x, float3 rgb) \{\n return float3(rgb.x*x, rgb.y*x, rgb.z*x);\n \}\n\n float min_f3(float3 a) \{\n return min( a.x, min( a.y, a.z));\n \}\n\n float max_f3(float3 a) \{\n return max( a.x, max( a.y, a.z));\n \}\n\n float rgb_2_saturation( float3 rgb ) \{\n return ( max( max_f3(rgb), 1e-10) - max( min_f3(rgb), 1e-10)) / max( max_f3(rgb), 1e-2);\n \}\n\n float sigmoid_shaper( float x) \{\n float t = max( float(1. - fabs( float(x / 2.))), float(0));\n float y = 1. + sign(float(x)) * (1. - t * t);\n return y / 2.;\n \}\n\n float rgb_2_yc( float3 rgb, float ycRadiusWeight) \{\n // keyword arguments don't work with blink.. ycRadiusWeight default if not specified was 1.75\n float r = rgb.x; \n float g = rgb.y; \n float b = rgb.z;\n float chroma = sqrt(float(b*(b-g)+g*(g-r)+r*(r-b)));\n return ( b + g + r + ycRadiusWeight * chroma) / 3.;\n \}\n\n // ------- Glow module functions\n float glow_fwd( float ycIn, float glowGainIn, float glowMid) \{\n float glowGainOut;\n if (ycIn <= 2./3. * glowMid) \{\n glowGainOut = glowGainIn;\n \} else if ( ycIn >= 2. * glowMid) \{\n glowGainOut = 0.;\n \} else \{\n glowGainOut = glowGainIn * (glowMid / ycIn - 1./2.);\n \}\n return glowGainOut;\n \}\n\n float glow_inv( float ycOut, float glowGainIn, float glowMid) \{\n float glowGainOut;\n if (ycOut <= ((1 + glowGainIn) * 2./3. * glowMid)) \{\n glowGainOut = -glowGainIn / (1 + glowGainIn);\n \} else if ( ycOut >= (2. * glowMid)) \{\n glowGainOut = 0.;\n \} else \{\n glowGainOut = glowGainIn * (glowMid / ycOut - 1./2.) / (glowGainIn / 2. - 1.);\n \}\n return glowGainOut;\n \}\n\n void process() \{\n float3 aces = float3(src().x, src().y, src().z);\n\n // --- Glow module --- //\n float saturation = rgb_2_saturation(aces);\n float s = sigmoid_shaper( (saturation - 0.4) / 0.2);\n float ycIn = rgb_2_yc( aces, 1.75);\n\n float glow;\n if ( invert == 0 ) \{\n glow = 1. + glow_fwd( ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);\n aces = mult_f_f3( glow, aces);\n \}\n else \{\n glow = 1. + glow_inv( ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);\n aces = mult_f_f3( ( glow), aces);\n \}\n \n dst() = float4(aces.x, aces.y, aces.z, src().w);\n \}\n\};"
useGPUIfAvailable {{parent.use_gpu}}
vectorize {{parent.vectorize}}
rebuild ""
ACES_rrt_sweetener_glow_module_RRT_GLOW_GAIN 0.05
ACES_rrt_sweetener_glow_module_RRT_GLOW_MID 0.08
rebuild_finalise ""
name rrt_sweetener_glow_module
xpos -1250
ypos -1096
}
BlinkScript {
recompileCount 7
ProgramGroup 1
KernelDescription "2 \"ACES_rrt_sweeteners\" iterate pixelWise 9f98be960666c115276f1fde84f0fa459ebb6c3833f44a05252af4ebb10f63b4 2 \"src\" Read Point \"dst\" Write Point 5 \"RRT_RED_SCALE\" Float 1 AAAAAA== \"RRT_RED_PIVOT\" Float 1 AAAAAA== \"RRT_RED_HUE\" Float 1 AAAAAA== \"RRT_RED_WIDTH\" Float 1 AAAAAA== \"invert\" Bool 1 AA== 5 \"RRT_RED_SCALE\" 1 1 \"RRT_RED_PIVOT\" 1 1 \"RRT_RED_HUE\" 1 1 \"RRT_RED_WIDTH\" 1 1 \"invert\" 1 1 0"
kernelSource "kernel ACES_rrt_sweeteners : public ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\nparam:\n // User controllable parameters\n float RRT_RED_SCALE;\n float RRT_RED_PIVOT;\n float RRT_RED_HUE;\n float RRT_RED_WIDTH;\n bool invert;\n\n // // Red modifier constants\n // RRT_RED_SCALE = 0.82;\n // RRT_RED_PIVOT = 0.03;\n // RRT_RED_HUE = 0.;\n // RRT_RED_WIDTH = 135.;\n\n\n float min_f3(float3 a) \{\n return min( a.x, min( a.y, a.z));\n \}\n\n float max_f3(float3 a) \{\n return max( a.x, max( a.y, a.z));\n \}\n\n float rgb_2_saturation( float3 rgb ) \{\n return ( max( max_f3(rgb), 1e-10) - max( min_f3(rgb), 1e-10)) / max( max_f3(rgb), 1e-2);\n \}\n\n float sigmoid_shaper( float x) \{\n float t = max( float(1. - fabs( float(x / 2.))), float(0));\n float y = 1. + sign(float(x)) * (1. - t * t);\n return y / 2.;\n \}\n\n float rgb_2_yc( float3 rgb, float ycRadiusWeight) \{\n // keyword arguments don't work with blink.. ycRadiusWeight default if not specified was 1.75\n float r = rgb.x; \n float g = rgb.y; \n float b = rgb.z;\n float chroma = sqrt(float(b*(b-g)+g*(g-r)+r*(r-b)));\n return ( b + g + r + ycRadiusWeight * chroma) / 3.;\n \}\n\n // ------- Glow module functions\n float glow_fwd( float ycIn, float glowGainIn, float glowMid) \{\n float glowGainOut;\n if (ycIn <= 2./3. * glowMid) \{\n glowGainOut = glowGainIn;\n \} else if ( ycIn >= 2. * glowMid) \{\n glowGainOut = 0.;\n \} else \{\n glowGainOut = glowGainIn * (glowMid / ycIn - 1./2.);\n \}\n return glowGainOut;\n \}\n\n // Transformations from RGB to other color representations\n float rgb_2_hue( float3 rgb) \n \{\n // Returns a geometric hue angle in degrees (0-360) based on RGB values.\n // For neutral colors, hue is undefined and the function will return a quiet NaN value.\n float hue;\n if (rgb.x == rgb.y && rgb.y == rgb.z) \{\n hue = 0.; // RGB triplets where RGB are equal have an undefined hue\n \} else \{\n hue = (180./3.14159265359) * atan2( sqrt(3)*(rgb.y-rgb.z), 2*rgb.x-rgb.y-rgb.z);\n \}\n if (hue < 0.) hue = hue + 360.;\n return hue;\n \}\n\n float center_hue( float hue, float centerH) \{\n float hueCentered = hue - centerH;\n if (hueCentered < -180.) hueCentered = hueCentered + 360.;\n else if (hueCentered > 180.) hueCentered = hueCentered - 360.;\n return hueCentered;\n \}\n\n float cubic_basis_shaper( float x, float w) \{\n float M\[4]\[4] = \{ \{ -1./6, 3./6, -3./6, 1./6 \},\n \{ 3./6, -6./6, 3./6, 0./6 \},\n \{ -3./6, 0./6, 3./6, 0./6 \},\n \{ 1./6, 4./6, 1./6, 0./6 \} \};\n \n double knots\[5] = \{ -w/2.,\n -w/4.,\n 0.,\n w/4.,\n w/2. \};\n float y = 0;\n if ((x > knots\[0]) && (x < knots\[4])) \{ \n float knot_coord = (x - knots\[0]) * 4./w; \n int j = knot_coord;\n float t = knot_coord - j;\n float monomials\[4] = \{ t*t*t, t*t, t, 1. \};\n // (if/else structure required for compatibility with CTL < v1.5.)\n if ( j == 3) \{\n y = monomials\[0] * M\[0]\[0] + monomials\[1] * M\[1]\[0] + \n monomials\[2] * M\[2]\[0] + monomials\[3] * M\[3]\[0];\n \} else if ( j == 2) \{\n y = monomials\[0] * M\[0]\[1] + monomials\[1] * M\[1]\[1] + \n monomials\[2] * M\[2]\[1] + monomials\[3] * M\[3]\[1];\n \} else if ( j == 1) \{\n y = monomials\[0] * M\[0]\[2] + monomials\[1] * M\[1]\[2] + \n monomials\[2] * M\[2]\[2] + monomials\[3] * M\[3]\[2];\n \} else if ( j == 0) \{\n y = monomials\[0] * M\[0]\[3] + monomials\[1] * M\[1]\[3] + \n monomials\[2] * M\[2]\[3] + monomials\[3] * M\[3]\[3];\n \} else \{\n y = 0.0;\n \}\n \}\n return y * 3/2.;\n \}\n\n\n void process() \{\n float3 aces = float3(src().x, src().y, src().z);\n\n float saturation = rgb_2_saturation(aces);\n\n // --- Red modifier --- //\n float hue = rgb_2_hue( aces);\n float centeredHue = center_hue( hue, RRT_RED_HUE);\n float hueWeight = cubic_basis_shaper( centeredHue, RRT_RED_WIDTH);\n\n if ( invert == 0 ) \{\n aces.x = aces.x + hueWeight * saturation * (RRT_RED_PIVOT - aces.x) * (1. - RRT_RED_SCALE);\n \} \n else \{ // invert red modifier: note that this is not mathematically perfect\n float minChan;\n if (centeredHue < 0) \{ // min_f3(aces) = aces\[1] (i.e. magenta-red)\n minChan = aces.y;\n \} else \{ // min_f3(aces) = aces\[2] (i.e. yellow-red)\n minChan = aces.z;\n \}\n float a = hueWeight * (1. - RRT_RED_SCALE) - 1.;\n float b = aces.x - hueWeight * (RRT_RED_PIVOT + minChan) * (1. - RRT_RED_SCALE);\n float c = hueWeight * RRT_RED_PIVOT * minChan * (1. - RRT_RED_SCALE);\n aces.x = ( -b - sqrt( float(b * b - 4. * a * c )) ) / ( 2. * a);\n \}\n\n dst() = float4(aces.x, aces.y, aces.z, src().w);\n \}\n\};"
useGPUIfAvailable {{parent.use_gpu}}
vectorize {{parent.vectorize}}
rebuild ""
ACES_rrt_sweeteners_RRT_RED_SCALE 0.82
ACES_rrt_sweeteners_RRT_RED_PIVOT 0.03
ACES_rrt_sweeteners_RRT_RED_WIDTH 135
rebuild_finalise ""
name rrt_sweetener_red_modifier
xpos -1250
ypos -1048
}
Clamp {
channels rgb
maximum_enable false
name clamp_f3_min
label "Clamp Negative Values"
xpos -1250
ypos -976
}
ColorMatrix {
matrix {
{1.451439381 -0.2365107685 -0.2149285674}
{-0.07655383646 1.176229835 -0.09967593104}
{0.008316127583 -0.0060324613 0.997716248}
}
name ColorMatrix15
label "ACES to ACEScg"
xpos -1250
ypos -928
}
Clamp {
channels rgb
maximum 65535
name clamp_f3_
label "clamp to HALF_MAX"
xpos -1250
ypos -880
}
ColorMatrix {
matrix {
{{"(1.0 - sat) * rgb2Y.x + sat"} {"(1.0 - sat) * rgb2Y.y"} {"(1.0 - sat) * rgb2Y.z"}}
{{"(1.0 - sat) * rgb2Y.x"} {"(1.0 - sat) * rgb2Y.y + sat"} {"(1.0 - sat) * rgb2Y.z"}}
{{"(1.0 - sat) * rgb2Y.x"} {"(1.0 - sat) * rgb2Y.y"} {"(1.0 - sat) * rgb2Y.z + sat"}}
}
name ColorMatrix
label "// --- Global desaturation --- //\nrgbPre = mult_f3_f33( rgbPre, RRT_SAT_MAT);"
xpos -1250
ypos -790
addUserKnob {20 params}
addUserKnob {13 rgb2Y}
rgb2Y {0.27222875 0.67408174 0.05368952}
addUserKnob {7 sat}
sat 0.96
}
BlinkScript {
recompileCount 436
ProgramGroup 1
KernelDescription "2 \"AcesSSTSKernel\" iterate pixelWise 777c75870bbc7fdb9e01da86019d098ae651932ef41328afda5c5c9c18fedc40 2 \"src\" Read Point \"dst\" Write Point 7 \"disp_lum\" Float 3 AAAAAAAAAAAAAAAAAAAAAA== \"override_curve_params\" Bool 1 AA== \"knee\" Float 1 AAAAAA== \"shoulder\" Float 1 AAAAAA== \"slope\" Float 3 AAAAAAAAAAAAAAAAAAAAAA== \"exposure\" Float 1 AAAAAA== \"invert\" Bool 1 AA== 7 \"disp_lum\" 3 1 \"override_curve_params\" 1 1 \"knee\" 1 1 \"shoulder\" 1 1 \"slope\" 3 1 \"exposure\" 1 1 \"invert\" 1 1 17 \"MIN_STOP_SDR\" Float 1 1 AAAAAA== \"MAX_STOP_SDR\" Float 1 1 AAAAAA== \"MIN_STOP_RRT\" Float 1 1 AAAAAA== \"MAX_STOP_RRT\" Float 1 1 AAAAAA== \"MIN_LUM_SDR\" Float 1 1 AAAAAA== \"MAX_LUM_SDR\" Float 1 1 AAAAAA== \"MIN_LUM_RRT\" Float 1 1 AAAAAA== \"MAX_LUM_RRT\" Float 1 1 AAAAAA== \"Min\" Float 3 1 AAAAAAAAAAAAAAAAAAAAAA== \"Mid\" Float 3 1 AAAAAAAAAAAAAAAAAAAAAA== \"Max\" Float 3 1 AAAAAAAAAAAAAAAAAAAAAA== \"expShift\" Float 1 1 AAAAAA== \"coefsLow\" Float 1 5 AAAAAAAAAAAAAAAAAAAAAAAAAAA= \"coefsHigh\" Float 1 5 AAAAAAAAAAAAAAAAAAAAAAAAAAA= \"N_KNOTS_LOW\" Int 1 1 AAAAAA== \"N_KNOTS_HIGH\" Int 1 1 AAAAAA== \"M1\" Float 9 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
kernelSource "kernel AcesSSTSKernel : public ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\nparam:\n // User controllable parameters\n float3 disp_lum;\n bool override_curve_params;\n float knee;\n float shoulder;\n float3 slope;\n float exposure;\n bool invert;\n\nlocal:\n float MIN_STOP_SDR;\n float MAX_STOP_SDR;\n float MIN_STOP_RRT;\n float MAX_STOP_RRT;\n float MIN_LUM_SDR;\n float MAX_LUM_SDR;\n float MIN_LUM_RRT;\n float MAX_LUM_RRT;\n float3 Min;\n float3 Mid;\n float3 Max;\n float expShift;\n float coefsLow\[5];\n float coefsHigh\[5];\n int N_KNOTS_LOW;\n int N_KNOTS_HIGH;\n float3x3 M1;\n\n // -------------------------------------------------------\n // Utility Functions\n // -------------------------------------------------------\n\n // 1D interpolate: return y value at some point p in x\n // This function differs from the interpolate1D CTL implementation.\n // It is limited to 2 float2 vectors, x and y\n // given a position p between x.x and x.y, it returns an interpolated\n // value between y.x and y.y\n // CTL_table\[2]\[2] = \{ \{ A, B \}, \{ C, D \} \};\n // = \n // float2 x = float2(A, C)\n // float2 y = float2(B, D)\n float interpolate1D(float2 x, float2 y, float p) \{\n if (p <= x.x) \{\n return y.x;\n \} else if (p >= x.y) \{\n return y.y;\n \} else \{\n float slope = (y.y-y.x) / (x.y-x.x);\n return y.x + slope * (p-x.x);\n \}\n \}\n\n // multiply a float3 by a matrix3x3\n float3 mult_f3_f33( float3 src, float3x3 mtx) \{\n return float3(mtx\[0]\[0] * src.x + mtx\[0]\[1] * src.y + \n mtx\[0]\[2] * src.z, mtx\[1]\[0] * src.x + mtx\[1]\[1] * src.y + \n mtx\[1]\[2] * src.z, mtx\[2]\[0] * src.x + mtx\[2]\[1] * src.y + \n mtx\[2]\[2] * src.z);\n \}\n\n // dot product of two 1x3 matrices\n float dot_f3_f3( float3 A, float3 B) \{\n return (A.x*B.x)+(A.y*B.y)+(A.z*B.z);\n \}\n\n // Return interpolated minimum ACES value given a minimum luminance value.\n float lookup_ACESmin( float minLum ) \{\n float2 rangeLum = float2(log10(float(MIN_LUM_RRT)), log10(float(MIN_LUM_SDR)));\n float2 rangeStops = float2(MIN_STOP_RRT, MIN_STOP_SDR);\n return 0.18*pow( float(2), float(interpolate1D( rangeLum, rangeStops, log10( float(minLum)))));\n \}\n // Return interpolated maximum ACES value given a maximum luminance value.\n float lookup_ACESmax( float maxLum ) \{\n float2 rangeLum = float2(log10(float(MAX_LUM_SDR)), log10(float(MAX_LUM_RRT)));\n float2 rangeStops = float2(MAX_STOP_SDR, MAX_STOP_RRT);\n return 0.18*pow( float(2), float(interpolate1D( rangeLum, rangeStops, log10( float(maxLum)))));\n \}\n\n void init_coefsLow( float3 TsPointLow, float3 TsPointMid ) \{\n // :145 float cLow\[5] = init_coefsLow( MIN_PT, MID_PT);\n float knotIncLow = (log10(TsPointMid.x) - log10(TsPointLow.x)) / 3.0;\n // DeterTsPointLowe two lowest coefficients (straddling TsPointLowPt)\n coefsLow\[0] = (TsPointLow.z * (log10(float(TsPointLow.x))-0.5*knotIncLow)) + ( log10(float(TsPointLow.y)) - TsPointLow.z * log10(float(TsPointLow.x)));\n coefsLow\[1] = (TsPointLow.z * (log10(float(TsPointLow.x))+0.5*knotIncLow)) + ( log10(float(TsPointLow.y)) - TsPointLow.z * log10(float(TsPointLow.x)));\n // DeterTsPointLowe two highest coefficients (straddling TsPointMidPt)\n coefsLow\[3] = (TsPointMid.z * (log10(float(TsPointMid.x))-0.5*knotIncLow)) + ( log10(float(TsPointMid.y)) - TsPointMid.z * log10(float(TsPointMid.x)));\n coefsLow\[4] = (TsPointMid.z * (log10(float(TsPointMid.x))+0.5*knotIncLow)) + ( log10(float(TsPointMid.y)) - TsPointMid.z * log10(float(TsPointMid.x)));\n // TsPointMiddle coefficient (which defines the \"sharpness of the bend\") is linearly interpolated\n float2 bendsLowA = float2(MIN_STOP_RRT, MIN_STOP_SDR);\n float2 bendsLowB = float2(0.18, 0.35);\n float pctLow;\n if (override_curve_params == 1) \{\n pctLow = knee;\n \}\n else \{\n pctLow = interpolate1D(bendsLowA, bendsLowB, log2(float(TsPointLow.x/0.18)));\n \}\n coefsLow\[2] = log10(float(TsPointLow.y)) + pctLow*(log10(float(TsPointMid.y))-log10(float(TsPointLow.y)));\n \}\n\n void init_coefsHigh( float3 TsPointMid, float3 TsPointMax ) \{\n // :146 float cHigh\[5] = init_coefsHigh( MID_PT, MAX_PT);\n float knotIncHigh = (log10(TsPointMax.x) - log10(TsPointMid.x)) / 3.;\n // DeterMine two lowest coefficients (straddling MidPt)\n coefsHigh\[0] = (TsPointMid.z * (log10(float(TsPointMid.x))-0.5*knotIncHigh)) + ( log10(float(TsPointMid.y)) - TsPointMid.z * log10(float(TsPointMid.x)));\n coefsHigh\[1] = (TsPointMid.z * (log10(float(TsPointMid.x))+0.5*knotIncHigh)) + ( log10(float(TsPointMid.y)) - TsPointMid.z * log10(float(TsPointMid.x)));\n // DeterMide two highest coefficients (straddling TsPointMaxPt)\n coefsHigh\[3] = (TsPointMax.z * (log10(float(TsPointMax.x))-0.5*knotIncHigh)) + ( log10(float(TsPointMax.y)) - TsPointMax.z * log10(float(TsPointMax.x)));\n coefsHigh\[4] = (TsPointMax.z * (log10(float(TsPointMax.x))+0.5*knotIncHigh)) + ( log10(float(TsPointMax.y)) - TsPointMax.z * log10(float(TsPointMax.x)));\n // Middle coefficient (which defines the \"sharpness of the bend\") is linearly interpolated\n float2 bendsHighA = float2(MAX_STOP_SDR, MAX_STOP_RRT);\n float2 bendsHighB = float2(0.89, 0.90);\n float pctHigh;\n if (override_curve_params == 1) \{\n pctHigh = shoulder;\n \}\n else \{\n pctHigh = interpolate1D(bendsHighA, bendsHighB, log2(float(TsPointMax.x/0.18)));\n \}\n coefsHigh\[2] = log10(float(TsPointMid.y)) + pctHigh*(log10(float(TsPointMax.y))-log10(float(TsPointMid.y)));\n \}\n\n float shift( float in, float expShift) \{\n return pow(float(2), (log2(float(in)) - expShift));\n \}\n\n void init_TsParams( float minLum, float maxLum, float exp_shift ) \{\n // ACESlib.SSTS.ctl :136 init_TsParams \n // Min Mid and Max is a float3 :\n // x = lum (aces), y = lum (cd/m^2), z = slope\n\n // override slope with default values used in AMPAS CTL\n if (override_curve_params == 1) \{\n Min = float3(lookup_ACESmin(minLum), minLum, float(slope.x));\n Mid = float3(0.18, 4.8, float(slope.y));\n Max = float3(lookup_ACESmax(maxLum), maxLum, float(slope.z)); \n \}\n else \{\n Min = float3(lookup_ACESmin(minLum), minLum, float(0.0));\n Mid = float3(0.18, 4.8, float(1.55));\n Max = float3(lookup_ACESmax(maxLum), maxLum, float(0.0));\n \}\n\n // init coefsLow and coefsHigh (directly sets local variables).\n init_coefsLow( Min, Mid );\n init_coefsHigh( Mid, Max );\n\n // :140 - init_TsParams : Exposure Shift\n Min.x = shift(lookup_ACESmin(minLum), exp_shift);\n Mid.x = shift(0.18, exp_shift);\n Max.x = shift(lookup_ACESmax(maxLum), exp_shift);\n\n // PARAMS = \n // float3 Min / float3 Mid / float3 Max \n // coefsLow\[5]\n // coefsHigh\[5]\n \}\n\n void init() \{\n // Textbook monomial to basis-function conversion matrix. (Used in tonescale)\n MIN_STOP_SDR = -6.5;\n MAX_STOP_SDR = 6.5;\n MIN_STOP_RRT = -15.;\n MAX_STOP_RRT = 18.;\n MIN_LUM_SDR = 0.02;\n MAX_LUM_SDR = 48.0;\n MIN_LUM_RRT = 0.0001;\n MAX_LUM_RRT = 10000.0;\n // Monomial to basis function\n float Marray\[] = \{0.5, -1.0, 0.5, \n -1.0, 1.0, 0.0, \n 0.5, 0.5, 0.0\};\n M1.setArray(Marray);\n\n N_KNOTS_LOW = 4;\n N_KNOTS_HIGH = 4;\n\n // Get min / max lum from user\n float Y_MIN = disp_lum.x;\n float Y_MID = disp_lum.y;\n float Y_MAX = disp_lum.z;\n\n\n init_TsParams( Y_MIN, Y_MAX, 0.0 );\n\n // Override expShift\n if (override_curve_params != 1) \{\n expShift = 0.0;\n \} else \{\n expShift = exposure;\n \}\n\n // Define expShift from inv_ssts\n expShift = (log2(inv_ssts(Y_MID)) - log2(0.18)) + expShift;\n\n // expShift = log2(inv_ssts(Y_MID)) - log2(0.18);\n\n init_TsParams( Y_MIN, Y_MAX, expShift );\n \}\n\n\n // ACES Single Stage Tone Scale\n float ssts( float x ) \{\n\n // Take the log: clamp min to HALF_MIN\n float logx = log10(max(x, 5.96046448e-08));\n float logy;\n\n // Calculate values for linear extension in shadows\n if (logx <= log10(float(Min.x))) \{\n logy = logx * Min.z + (log10(float(Min.y))) - \n Min.z * log10(float(Min.x));\n \}\n // Calculate values for lower half of S-curve, shadows \n else if (( logx > log10(float(Min.x)) ) && ( logx < log10(float(Mid.x)) )) \{\n float knot_coord = (N_KNOTS_LOW-1) * (logx-log10(float(Min.x)))/\n (log10(float(Mid.x))-log10(float(Min.x)));\n int j = knot_coord;\n float t = knot_coord - j;\n float3 cf = float3(coefsLow\[j], coefsLow\[j + 1], coefsLow\[j + 2]);\n float3 monomials = float3(t * t, t, 1.);\n logy = dot_f3_f3(monomials, mult_f3_f33(cf, M1));\n \}\n // Calculate values for upper half of S-curve, highlights\n else if (( logx >= log10(float(Mid.x)) ) && ( logx < log10(float(Max.x)) )) \{\n float knot_coord = (N_KNOTS_HIGH-1) * (logx-log10(float(Mid.x)))/\n (log10(float(Max.x))-log10(float(Mid.x)));\n int j = knot_coord;\n float t = knot_coord - j;\n float3 cf = float3(coefsHigh\[j], coefsHigh\[j + 1], coefsHigh\[j + 2]); \n float3 monomials = float3(t * t, t, 1.);\n logy = dot_f3_f3(monomials, mult_f3_f33(cf, M1));\n \}\n // Calculate values for linear extension in highlights\n else \{ // if ( logx >= log10(float(Max.x)) ) \{\n logy = logx * Max.z + ( log10(float(Max.y)) - Max.z * log10(float(Max.x)) );\n \}\n // un-log\n return pow(float(10),logy);\n \}\n\n\n // ACES Inverse Single Stage Tone Scale\n float inv_ssts( float y ) \{\n\n float KNOT_INC_LOW = (log10(float(Mid.x)) - log10(float(Min.x))) / (N_KNOTS_LOW - 1.);\n float KNOT_INC_HIGH = (log10(float(Max.x)) - log10(float(Mid.x))) / (N_KNOTS_HIGH - 1.);\n\n // KNOT_Y is luminance of the spline at each knot\n // Error 1: variable length arrays are not supported in OpenCL\n // float __KNOT_Y_LOW_38\[N_KNOTS_LOW];\n // Setting array length to 4 manually as a workaround... :(\n float KNOT_Y_LOW\[ 4];\n for (int i = 0; i < N_KNOTS_LOW; i = i+1) \{\n KNOT_Y_LOW\[ i] = ( coefsLow\[i] + coefsLow\[i+1]) / 2.;\n \}\n // Setting array length to 4 manually as a workaround...\n float KNOT_Y_HIGH\[ 4];\n for (int i = 0; i < N_KNOTS_HIGH; i = i+1) \{\n KNOT_Y_HIGH\[ i] = ( coefsHigh\[i] + coefsHigh\[i+1]) / 2.;\n \};\n\n float logy = log10( max(y, 1e-10));\n float logx;\n\n if (logy <= log10(float(Min.y))) \{\n logx = log10(float(Min.x));\n\n \} else if ( (logy > log10(float(Min.y))) && (logy <= log10(float(Mid.y))) ) \{\n int j;\n float3 cf;\n if ( logy > KNOT_Y_LOW\[ 0] && logy <= KNOT_Y_LOW\[ 1]) \{\n cf.x = coefsLow\[0]; cf.y = coefsLow\[1]; cf.z = coefsLow\[2]; j = 0;\n \} else if ( logy > KNOT_Y_LOW\[ 1] && logy <= KNOT_Y_LOW\[ 2]) \{\n cf.x = coefsLow\[1]; cf.y = coefsLow\[2]; cf.z = coefsLow\[3]; j = 1;\n \} else if ( logy > KNOT_Y_LOW\[ 2] && logy <= KNOT_Y_LOW\[ 3]) \{\n cf.x = coefsLow\[2]; cf.y = coefsLow\[3]; cf.z = coefsLow\[4]; j = 2;\n \} \n\n float3 tmp = mult_f3_f33( cf, M1);\n float a = tmp.x;\n float b = tmp.y;\n float c = tmp.z;\n c = c - logy;\n\n const float d = sqrt(float(b * b - 4. * a * c));\n\n const float t = ( 2. * c) / ( -d - b);\n\n logx = log10(float(Min.x)) + ( t + j) * KNOT_INC_LOW;\n\n \} else if ( (logy > log10(float(Mid.y))) && (logy < log10(float(Max.y))) ) \{\n int j;\n float3 cf;\n if ( logy >= KNOT_Y_HIGH\[ 0] && logy <= KNOT_Y_HIGH\[ 1]) \{\n cf.x = coefsHigh\[0]; cf.y = coefsHigh\[1]; cf.z = coefsHigh\[2]; j = 0;\n \} else if ( logy > KNOT_Y_HIGH\[ 1] && logy <= KNOT_Y_HIGH\[ 2]) \{\n cf.x = coefsHigh\[1]; cf.y = coefsHigh\[2]; cf.z = coefsHigh\[3]; j = 1;\n \} else if ( logy > KNOT_Y_HIGH\[ 2] && logy <= KNOT_Y_HIGH\[ 3]) \{\n cf.x = coefsHigh\[2]; cf.y = coefsHigh\[3]; cf.z = coefsHigh\[4]; j = 2;\n \} \n\n float3 tmp = mult_f3_f33( cf, M1);\n\n float a = tmp.x;\n float b = tmp.y;\n float c = tmp.z;\n c = c - logy;\n\n const float d = sqrt( float(b * b - 4. * a * c));\n\n const float t = ( 2. * c) / ( -d - b);\n\n logx = log10(float(Mid.x)) + ( t + j) * KNOT_INC_HIGH;\n\n \} else \{ //if ( logy >= log10(float(Max.y)) ) \{\n\n logx = log10(float(Max.x));\n\n \}\n\n return pow(10, logx);\n\n \}\n\n void process() \{\n\n if (invert == 1 ) \{\n dst() = float4(inv_ssts(src().x), inv_ssts(src().y), inv_ssts(src().z), src().w);\n \}\n else \{\n dst() = float4(ssts(src().x), ssts(src().y), ssts(src().z), src().w);\n \}\n \}\n\};"
useGPUIfAvailable {{parent.use_gpu}}
vectorize {{parent.vectorize}}
rebuild ""
AcesSSTSKernel_disp_lum {{"use_c9 ? 0.0001 : parent.lum"} {parent.lum} {"use_c9 ? 10000 : parent.lum"}}
AcesSSTSKernel_override_curve_params {{parent.override_ssts_params}}
AcesSSTSKernel_knee {{parent.pctLow}}
AcesSSTSKernel_shoulder {{parent.pctHigh}}
AcesSSTSKernel_slope {{parent.slope} {parent.slope} {parent.slope}}
AcesSSTSKernel_exposure {{parent.exposure}}
rebuild_finalise ""
name ACES_SSTS
xpos -1250
ypos -520
}
Dot {
name Dot23
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos -462
}
set N6d9505d0 [stack 0]
Dot {
name Dot22
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1656
ypos -462
}
ColorMatrix {
matrix {
{1.4514395 -0.2365107536 -0.2149285972}
{-0.07655385882 1.176229835 -0.09967592359}
{0.008316127583 -0.006032462232 0.9977163076}
}
name ColorMatrix12
label "ACEScg to ACES"
xpos -1690
ypos -400
}
Dot {
name Dot21
label " OCES"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1656
ypos 2658
}
push $N6d9505d0
Dot {
name Dot28
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos -342
}
set N6d04f680 [stack 0]
BlinkScript {
recompileCount 3
ProgramGroup 1
KernelDescription "2 \"ACES_segmented_spline_c9\" iterate pixelWise 4b980beb88a808b7875da41c3b7df42df009b5085dccf81d73bd31384e611901 2 \"src\" Read Point \"dst\" Write Point 2 \"invert\" Bool 1 AA== \"odt_type\" Int 1 AAAAAA== 2 \"invert\" 1 1 \"odt_type\" 1 1 10 \"Min\" Float 2 1 AAAAAAAAAAA= \"Mid\" Float 2 1 AAAAAAAAAAA= \"Max\" Float 2 1 AAAAAAAAAAA= \"slopeLow\" Float 1 1 AAAAAA== \"slopeHigh\" Float 1 1 AAAAAA== \"coefsLow\" Float 1 10 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== \"coefsHigh\" Float 1 10 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== \"N_KNOTS_LOW\" Int 1 1 AAAAAA== \"N_KNOTS_HIGH\" Int 1 1 AAAAAA== \"M\" Float 9 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
kernelSource "kernel ACES_segmented_spline_c9 : public ImageComputationKernel<ePixelWise>\n\{\n Image<eRead, eAccessPoint, eEdgeClamped> src;\n Image<eWrite> dst;\n\nparam:\n // User controllable parameters\n bool invert;\n int odt_type;\n\nlocal:\n float2 Min;\n float2 Mid;\n float2 Max;\n float slopeLow;\n float slopeHigh;\n float coefsLow\[10];\n float coefsHigh\[10];\n int N_KNOTS_LOW;\n int N_KNOTS_HIGH;\n\n float3x3 M;\n\n\n // multiply a float3 by a matrix3x3\n float3 mult_f3_f33( float3 src, float3x3 mtx) \{\n return float3(mtx\[0]\[0] * src.x + mtx\[0]\[1] * src.y + \n mtx\[0]\[2] * src.z, mtx\[1]\[0] * src.x + mtx\[1]\[1] * src.y + \n mtx\[1]\[2] * src.z, mtx\[2]\[0] * src.x + mtx\[2]\[1] * src.y + \n mtx\[2]\[2] * src.z);\n \}\n\n // dot product of two 1x3 matrices\n float dot_f3_f3( float3 A, float3 B) \{\n return (A.x*B.x)+(A.y*B.y)+(A.z*B.z);\n \}\n\n void init() \{\n\n // Set up ODT prameters : switch with int odt_type\n // Assigning arrays the normal way with <type> name\[] = \{val, val, val\}; doesn't work in blinkscript :(\n // odt_type = 0 : ODT_48nits\n if (odt_type == 0) \{\n // coefsLow\[10]\n coefsLow\[0] = -1.6989700043;\n coefsLow\[1] = -1.6989700043;\n coefsLow\[2] = -1.4779000000;\n coefsLow\[3] = -1.2291000000;\n coefsLow\[4] = -0.8648000000;\n coefsLow\[5] = -0.4480000000;\n coefsLow\[6] = 0.0051800000;\n coefsLow\[7] = 0.4511080334;\n coefsLow\[8] = 0.9113744414;\n coefsLow\[9] = 0.9113744414;\n // coefsHigh\[10]\n coefsHigh\[0] = 0.5154386965;\n coefsHigh\[1] = 0.8470437783;\n coefsHigh\[2] = 1.1358000000;\n coefsHigh\[3] = 1.3802000000;\n coefsHigh\[4] = 1.5197000000;\n coefsHigh\[5] = 1.5985000000;\n coefsHigh\[6] = 1.6467000000;\n coefsHigh\[7] = 1.6746091357;\n coefsHigh\[8] = 1.6878733390;\n coefsHigh\[9] = 1.6878733390;\n\n // Explicit casts to float are necessary for log10 calls in function to work :/\n // Explicitly calculating calls to segmented_spline_c5_fwd() to avoid having to implement this \n // here as well.\n Min = float2(float(0.00288), float(0.02));\n Mid = float2(float(4.8), float(4.8));\n Max = float2(float(1005.71936), float(48.0));\n slopeLow = 0.0;\n slopeHigh = 0.04;\n \}\n // odt_type = 1 : ODT_1000nits\n else if (odt_type == 1) \{\n // coefsLow\[10]\n coefsLow\[0] = -4.9706219331;\n coefsLow\[1] = -3.0293780669;\n coefsLow\[2] = -2.1262;\n coefsLow\[3] = -1.5105;\n coefsLow\[4] = -1.0578;\n coefsLow\[5] = -0.4668;\n coefsLow\[6] = 0.11938;\n coefsLow\[7] = 0.7088134201;\n coefsLow\[8] = 1.2911865799;\n coefsLow\[9] = 1.2911865799;\n // coefsHigh\[10]\n coefsHigh\[0] = 0.8089132070;\n coefsHigh\[1] = 1.1910867930;\n coefsHigh\[2] = 1.5683;\n coefsHigh\[3] = 1.9483;\n coefsHigh\[4] = 2.3083;\n coefsHigh\[5] = 2.6384;\n coefsHigh\[6] = 2.8595;\n coefsHigh\[7] = 2.9872608805;\n coefsHigh\[8] = 3.0127391195;\n coefsHigh\[9] = 3.0127391195;\n\n Min = float2(float(0.00014), float(0.0001));\n Mid = float2(float(4.8), float(10));\n Max = float2(float(4505.08447), float(1000));\n slopeLow = 3.0;\n slopeHigh = 0.06;\n \}\n // odt_type = 2 : ODT_2000nits\n else if (odt_type == 2) \{\n // coefsLow\[10]\n coefsLow\[0] = -4.9706219331;\n coefsLow\[1] = -3.0293780669;\n coefsLow\[2] = -2.1262;\n coefsLow\[3] = -1.5105;\n coefsLow\[4] = -1.0578;\n coefsLow\[5] = -0.4668;\n coefsLow\[6] = 0.11938;\n coefsLow\[7] = 0.7088134201;\n coefsLow\[8] = 1.2911865799;\n coefsLow\[9] = 1.2911865799;\n // coefsHigh\[10]\n coefsHigh\[0] = 0.8019952042;\n coefsHigh\[1] = 1.1980047958;\n coefsHigh\[2] = 1.5943000000;\n coefsHigh\[3] = 1.9973000000;\n coefsHigh\[4] = 2.3783000000;\n coefsHigh\[5] = 2.7684000000;\n coefsHigh\[6] = 3.0515000000;\n coefsHigh\[7] = 3.2746293562;\n coefsHigh\[8] = 3.3274306351;\n coefsHigh\[9] = 3.3274306351;\n\n Min = float2(float(0.00014), float(0.0001));\n Mid = float2(float(4.8), float(10));\n Max = float2(float(5771.86426), float(2000));\n slopeLow = 3.0;\n slopeHigh = 0.12;\n \}\n // odt_type = 3 : ODT_4000nits\n else if (odt_type == 3) \{\n // coefsLow\[10]\n coefsLow\[0] = -4.9706219331;\n coefsLow\[1] = -3.0293780669;\n coefsLow\[2] = -2.1262;\n coefsLow\[3] = -1.5105;\n coefsLow\[4] = -1.0578;\n coefsLow\[5] = -0.4668;\n coefsLow\[6] = 0.11938;\n coefsLow\[7] = 0.7088134201;\n coefsLow\[8] = 1.2911865799;\n coefsLow\[9] = 1.2911865799;\n // coefsHigh\[10]\n coefsHigh\[0] = 0.7973186613;\n coefsHigh\[1] = 1.2026813387;\n coefsHigh\[2] = 1.6093000000;\n coefsHigh\[3] = 2.0108000000;\n coefsHigh\[4] = 2.4148000000;\n coefsHigh\[5] = 2.8179000000;\n coefsHigh\[6] = 3.1725000000;\n coefsHigh\[7] = 3.5344995451;\n coefsHigh\[8] = 3.6696204376;\n coefsHigh\[9] = 3.6696204376;\n\n Min = float2(float(0.00014), float(0.0001));\n Mid = float2(float(4.8), float(10));\n Max = float2(float(6824.36572), float(2000));\n slopeLow = 3.0;\n slopeHigh = 0.3;\n \}\n\n // Monomial to basis function (Note: this is transposed compared to the AMPAS CTL)\n float Marray\[] = \{0.5, -1.0, 0.5, \n -1.0, 1.0, 0.0, \n 0.5, 0.5, 0.0\};\n M.setArray(Marray);\n\n // It seems as though if you define an int before an array, the int\n // could randomly get set to a really really high value :(\n N_KNOTS_LOW = 8;\n N_KNOTS_HIGH = 8;\n \}\n\n\n float segmented_spline_c9_fwd( float x ) \{\n // Take the log: clamp min to HALF_MIN\n float logx = log10(max(x, 5.96046448e-08));\n float logy;\n\n if ( logx <= log10(Min.x) ) \{ \n logy = logx * slopeLow + ( log10(Min.y) - slopeLow * log10(Min.x) );\n \} \n else if (( logx > log10(Min.x) ) && ( logx < log10(Mid.x) )) \{\n float knot_coord = (N_KNOTS_LOW-1) * (logx-log10(Min.x))/(log10(Mid.x)-log10(Min.x));\n int j = knot_coord;\n float t = knot_coord - j;\n float3 cf = float3(coefsLow\[ j], coefsLow\[ j + 1], coefsLow\[ j + 2]);\n float3 monomials = float3(t * t, t, 1. );\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M));\n \} \n else if (( logx >= log10(Mid.x) ) && ( logx < log10(Max.x) )) \{\n float knot_coord = (N_KNOTS_HIGH-1) * (logx-log10(Mid.x))/(log10(Max.x)-log10(Mid.x));\n int j = knot_coord;\n float t = knot_coord - j;\n float3 cf = float3(coefsHigh\[ j], coefsHigh\[ j + 1], coefsHigh\[ j + 2]);\n float3 monomials = float3(t * t, t, 1.);\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M));\n \} \n else \{ //if ( logIn >= log10(Max.x) ) \{ \n logy = logx * slopeHigh + ( log10(Max.y) - slopeHigh * log10(Max.x) );\n \}\n\n return pow(10, logy);\n \}\n\n\n\n float segmented_spline_c9_rev( float y ) \{ \n\n const float KNOT_INC_LOW = (log10(Mid.x) - log10(Min.x)) / (N_KNOTS_LOW - 1.);\n const float KNOT_INC_HIGH = (log10(Max.x) - log10(Mid.x)) / (N_KNOTS_HIGH - 1.);\n \n // KNOT_Y is luminance of the spline at each knot\n // Setting array length to 4 manually to work around \n // Error 1: variable length arrays are not supported in OpenCL\n\n float KNOT_Y_LOW\[ 8];\n for (int i = 0; i < N_KNOTS_LOW; i = i+1) \{\n KNOT_Y_LOW\[ i] = ( coefsLow\[i] + coefsLow\[i+1]) / 2.;\n \};\n\n float KNOT_Y_HIGH\[ 8];\n for (int i = 0; i < N_KNOTS_HIGH; i = i+1) \{\n KNOT_Y_HIGH\[ i] = ( coefsHigh\[i] + coefsHigh\[i+1]) / 2.;\n \};\n\n float logy = log10( max( y, 1e-10));\n float logx;\n\n if (logy <= log10(Min.y)) \{\n logx = log10(Min.x);\n \} \n else if ( (logy > log10(Min.y)) && (logy <= log10(Mid.y)) ) \{\n int j;\n float3 cf;\n if ( logy > KNOT_Y_LOW\[ 0] && logy <= KNOT_Y_LOW\[ 1]) \{\n cf\[ 0] = coefsLow\[0]; cf\[ 1] = coefsLow\[1]; cf\[ 2] = coefsLow\[2]; j = 0;\n \} else if ( logy > KNOT_Y_LOW\[ 1] && logy <= KNOT_Y_LOW\[ 2]) \{\n cf\[ 0] = coefsLow\[1]; cf\[ 1] = coefsLow\[2]; cf\[ 2] = coefsLow\[3]; j = 1;\n \} else if ( logy > KNOT_Y_LOW\[ 2] && logy <= KNOT_Y_LOW\[ 3]) \{\n cf\[ 0] = coefsLow\[2]; cf\[ 1] = coefsLow\[3]; cf\[ 2] = coefsLow\[4]; j = 2;\n \} else if ( logy > KNOT_Y_LOW\[ 3] && logy <= KNOT_Y_LOW\[ 4]) \{\n cf\[ 0] = coefsLow\[3]; cf\[ 1] = coefsLow\[4]; cf\[ 2] = coefsLow\[5]; j = 3;\n \} else if ( logy > KNOT_Y_LOW\[ 4] && logy <= KNOT_Y_LOW\[ 5]) \{\n cf\[ 0] = coefsLow\[4]; cf\[ 1] = coefsLow\[5]; cf\[ 2] = coefsLow\[6]; j = 4;\n \} else if ( logy > KNOT_Y_LOW\[ 5] && logy <= KNOT_Y_LOW\[ 6]) \{\n cf\[ 0] = coefsLow\[5]; cf\[ 1] = coefsLow\[6]; cf\[ 2] = coefsLow\[7]; j = 5;\n \} else if ( logy > KNOT_Y_LOW\[ 6] && logy <= KNOT_Y_LOW\[ 7]) \{\n cf\[ 0] = coefsLow\[6]; cf\[ 1] = coefsLow\[7]; cf\[ 2] = coefsLow\[8]; j = 6;\n \}\n \n const float3 tmp = mult_f3_f33( cf, M);\n float a = tmp\[ 0];\n float b = tmp\[ 1];\n float c = tmp\[ 2];\n c = c - logy;\n const float d = sqrt(float(b * b - 4. * a * c));\n const float t = ( 2. * c) / ( -d - b);\n logx = log10(Min.x) + ( t + j) * KNOT_INC_LOW;\n \} \n else if ( (logy > log10(Mid.y)) && (logy < log10(Max.y)) ) \{\n int j;\n float3 cf;\n if ( logy > KNOT_Y_HIGH\[ 0] && logy <= KNOT_Y_HIGH\[ 1]) \{\n cf\[ 0] = coefsHigh\[0]; cf\[ 1] = coefsHigh\[1]; cf\[ 2] = coefsHigh\[2]; j = 0;\n \} else if ( logy > KNOT_Y_HIGH\[ 1] && logy <= KNOT_Y_HIGH\[ 2]) \{\n cf\[ 0] = coefsHigh\[1]; cf\[ 1] = coefsHigh\[2]; cf\[ 2] = coefsHigh\[3]; j = 1;\n \} else if ( logy > KNOT_Y_HIGH\[ 2] && logy <= KNOT_Y_HIGH\[ 3]) \{\n cf\[ 0] = coefsHigh\[2]; cf\[ 1] = coefsHigh\[3]; cf\[ 2] = coefsHigh\[4]; j = 2;\n \} else if ( logy > KNOT_Y_HIGH\[ 3] && logy <= KNOT_Y_HIGH\[ 4]) \{\n cf\[ 0] = coefsHigh\[3]; cf\[ 1] = coefsHigh\[4]; cf\[ 2] = coefsHigh\[5]; j = 3;\n \} else if ( logy > KNOT_Y_HIGH\[ 4] && logy <= KNOT_Y_HIGH\[ 5]) \{\n cf\[ 0] = coefsHigh\[4]; cf\[ 1] = coefsHigh\[5]; cf\[ 2] = coefsHigh\[6]; j = 4;\n \} else if ( logy > KNOT_Y_HIGH\[ 5] && logy <= KNOT_Y_HIGH\[ 6]) \{\n cf\[ 0] = coefsHigh\[5]; cf\[ 1] = coefsHigh\[6]; cf\[ 2] = coefsHigh\[7]; j = 5;\n \} else if ( logy > KNOT_Y_HIGH\[ 6] && logy <= KNOT_Y_HIGH\[ 7]) \{\n cf\[ 0] = coefsHigh\[6]; cf\[ 1] = coefsHigh\[7]; cf\[ 2] = coefsHigh\[8]; j = 6;\n \}\n \n const float3 tmp = mult_f3_f33( cf, M);\n float a = tmp\[ 0];\n float b = tmp\[ 1];\n float c = tmp\[ 2];\n c = c - logy;\n const float d = sqrt( float(b * b - 4. * a * c));\n const float t = ( 2. * c) / ( -d - b);\n logx = log10(Mid.x) + ( t + j) * KNOT_INC_HIGH;\n \} \n else \{ //if ( logy >= log10(Max.y) ) \{\n logx = log10(Max.x);\n \}\n \n return pow(10, logx);\n\n \}\n\n\n\n void process() \{\n float3 aces = float3(src().x, src().y, src().z);\n\n if (invert == 0) \{\n aces = float3(segmented_spline_c9_fwd(aces.x), segmented_spline_c9_fwd(aces.y), segmented_spline_c9_fwd(aces.z));\n \} else \{\n aces = float3(segmented_spline_c9_rev(aces.x), segmented_spline_c9_rev(aces.y), segmented_spline_c9_rev(aces.z));\n \}\n\n dst() = float4(aces.x, aces.y, aces.z, src().w);\n \n // dst() = float4(log10(Min.x), log10(Mid.x), N_KNOTS_LOW, N_KNOTS_HIGH);\n\n \}\n\};"
useGPUIfAvailable {{parent.use_gpu}}
vectorize {{parent.vectorize}}
rebuild ""
rebuild_finalise ""
name segmented_spline_c9_
xpos -1140
ypos -352
}
push $N6d04f680
Switch {
inputs 2
which {{parent.use_c9}}
name Switch_c9
xpos -1250
ypos -298
}
Expression {
expr0 "(r - Ymin) / (Ymax - Ymin)"
expr1 "(g - Ymin) / (Ymax - Ymin)"
expr2 "(b - Ymin) / (Ymax - Ymin)"
expr3 1
name Y_2_linCV_f3_
xpos -1250
ypos 38
addUserKnob {20 Luminance}
addUserKnob {7 Ymin R 0.0001 0.02}
Ymin {{parent.lum.0}}
addUserKnob {7 Ymax R 48 10000}
Ymax {{parent.lum.2}}
}
Dot {
name Dot12
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos 282
}
set N6ba51a60 [stack 0]
Dot {
name Dot15
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1106
ypos 282
}
set N6b952b00 [stack 0]
Dot {
name Dot13
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -886
ypos 282
}
Dot {
name Dot16
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -886
ypos 354
}
set N6b550ef0 [stack 0]
Expression {
temp_name0 tr
temp_expr0 "(-r - c_x_0) / (c_x_1 - c_x_0)"
temp_name1 tg
temp_expr1 "(-g - c_x_0) / (c_x_1 - c_x_0)"
temp_name2 tb
temp_expr2 "(-b - c_x_0) / (c_x_1 - c_x_0)"
expr0 "tr < 0.0 ? -(tr * c_b + c_c) : tr > 1.0 ? r : -(( tr * c_a + c_b) * tr + c_c)"
expr1 "tg < 0.0 ? -(tg * c_b + c_c) : tg > 1.0 ? g : -(( tg * c_a + c_b) * tg + c_c)"
expr2 "tb < 0.0 ? -(tb * c_b + c_c) : tb > 1.0 ? b : -(( tb * c_a + c_b) * tb + c_c)"
name roll_white_fwd_1
xpos -920
ypos 398
addUserKnob {20 Params}
addUserKnob {7 new_wht}
new_wht 0.918
addUserKnob {7 c_width}
c_width 0.5
addUserKnob {7 c_x_0 +DISABLED}
c_x_0 -1
addUserKnob {7 c_x_1 +DISABLED}
c_x_1 {{"c_x_0 + c_width"}}
addUserKnob {7 c_y0 +DISABLED}
c_y0 {{-new_wht}}
addUserKnob {7 c_y1 +DISABLED}
c_y1 {{c_x_1}}
addUserKnob {7 c_m1 +DISABLED}
c_m1 {{"(c_x_1 - c_x_0)"}}
addUserKnob {7 c_a +DISABLED}
c_a {{"c_y0 - c_y1 + c_m1"}}
addUserKnob {7 c_b +DISABLED}
c_b {{"2 * (c_y1 - c_y0) - c_m1"}}
addUserKnob {7 c_c +DISABLED}
c_c {{c_y0}}
}
Expression {
temp_name0 SCALE
temp_expr0 0.96
temp_name1 NEW_WHT
temp_expr1 0.918
expr0 "min( r, NEW_WHT) * SCALE"
expr1 "min( g, NEW_WHT) * SCALE"
expr2 "min( b, NEW_WHT) * SCALE"
name Expression2
label "// Scale and clamp white to avoid casted highlights due to D60 simulation"
xpos -920
ypos 440
}
Dot {
name Dot11
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -886
ypos 498
}
push $N6b550ef0
Expression {
temp_name0 SCALE
temp_expr0 0.96362
expr0 "r * SCALE"
expr1 "g * SCALE"
expr2 "b * SCALE"
name mult_f_f3_
label D65
xpos -1030
ypos 344
}
push $N6b952b00
Switch {
inputs 2
which {{"parent.display_pri < 3"}}
name switch_wp_is_d65_
xpos -1140
ypos 350
}
Dot {
name Dot14
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1106
ypos 426
}
push $N6ba51a60
Switch {
inputs 2
which {{parent.d60_sim}}
name d60_sim_switch1
xpos -1250
ypos 422
}
Switch {
inputs 2
which {{"parent.display_pri == 3"}}
name switch_wp_is_dci_
xpos -1250
ypos 494
}
Dot {
name Dot26
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos 762
}
set Nd7828960 [stack 0]
ColorMatrix {
matrix {
{{"(1.0 - sat) * rgb2Y.x + sat"} {"(1.0 - sat) * rgb2Y.y"} {"(1.0 - sat) * rgb2Y.z"}}
{{"(1.0 - sat) * rgb2Y.x"} {"(1.0 - sat) * rgb2Y.y + sat"} {"(1.0 - sat) * rgb2Y.z"}}
{{"(1.0 - sat) * rgb2Y.x"} {"(1.0 - sat) * rgb2Y.y"} {"(1.0 - sat) * rgb2Y.z + sat"}}
}
name ColorMatrix3
label "// Apply desaturation to compensate \nfor luminance difference"
xpos -1140
ypos 746
addUserKnob {20 params}
addUserKnob {13 rgb2Y}
rgb2Y {0.27222875 0.67408174 0.05368952}
addUserKnob {7 sat}
sat 0.93
}
push $Nd7828960
Switch {
inputs 2
which {{"parent.eotf < 5 && display_pri < 2"}}
name Switch_eotf
label "Use if output is SDR"
xpos -1250
ypos 800
}
ColorMatrix {
matrix {
{0.6624541879 0.1340042055 0.1561876982}
{0.2722287476 0.6740817428 0.05368951708}
{-0.005574660841 0.004060741514 1.010339141}
}
name ColorMatrix1
label "ACES AP1 to XYZ"
xpos -1250
ypos 968
}
Dot {
name Dot8
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos 1146
}
set Nd6c28130 [stack 0]
Colorspace {
colorspace_in CIE-XYZ
colorspace_out CIE-Yxy
name Colorspace2
label "\[value colorspace_in] -> \[value colorspace_out]"
xpos -1140
ypos 1136
}
Clamp {
channels {rgba.red -rgba.green -rgba.blue none}
maximum_enable false
name ClampMin4
xpos -1140
ypos 1190
}
Expression {
expr0 "pow(r, DIM_SURROUND_GAMMA)"
expr1 g
expr2 b
channel3 none
name dark_to_dim3
xpos -1140
ypos 1214
addUserKnob {20 Params}
addUserKnob {7 DIM_SURROUND_GAMMA}
DIM_SURROUND_GAMMA 0.9811
}
Colorspace {
colorspace_in CIE-Yxy
colorspace_out CIE-XYZ
name Colorspace4
label "\[value colorspace_in] -> \[value colorspace_out]"
xpos -1140
ypos 1256
}
push $Nd6c28130
Switch {
inputs 2
which {{"(parent.eotf <= 4) ? parent.dark_to_dim : 0"}}
name DarkToDim_Switch
label "enable if sdr\nand dark_to_dim enabled"
xpos -1250
ypos 1250
}
Dot {
name Dot19
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos 1434
}
set Ncda77700 [stack 0]
Dot {
name Dot9
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1106
ypos 1434
}
set Ncdd78870 [stack 0]
ColorMatrix {
matrix {
{0.9872254133 -0.006114810705 0.01592640579}
{-0.007603884675 1.001874804 0.005322027951}
{0.003066040576 -0.005084238946 1.081519246}
}
name ColorMatrix2
label "CAT: Bradford\n D60 to D65"
xpos -1140
ypos 1466
}
set Nd8d59a30 [stack 0]
push $Ncdd78870
Dot {
name Dot10
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -996
ypos 1434
}
push $Nd8d59a30
Switch {
inputs 2
which {{parent.d60_sim}}
name d60_sim_switch
xpos -1140
ypos 1550
}
push $Ncda77700
Switch {
inputs 2
which {{"parent.display_pri < 3"}}
name switch_wp_is_d65_1
xpos -1250
ypos 1550
}
Switch {
inputs 2
which {{parent.force_d65_cat}}
name switch_force_d65_cat
xpos -1250
ypos 1598
}
Group {
name limit_to_primaries
label "Only enabled when display_pri != limiting_pri"
xpos -1250
ypos 1760
disable {{"!(parent.display_pri != parent.limiting_pri)"}}
addUserKnob {20 limit_to_primaries}
addUserKnob {4 limiting_pri l "limiting pri" M {Rec709 Rec2020 P3D65 P3DCI P3D60 ACEScg ACES XYZ}}
limiting_pri {{parent.limiting_pri}}
}
Input {
inputs 0
name Input
xpos -40
ypos -298
}
Dot {
name Dot1
label " XYZ to limiting primaries"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -6
ypos -198
}
set Nc8c458e0 [stack 0]
push $Nc8c458e0
ColorMatrix {
matrix {
{1.049811006 0 -9.748453158e-05}
{-0.4959030151 1.373313069 0.09824004024}
{4.020908051e-08 0 0.9912520051}
}
name ColorMatrix5
label "XYZ to ACES"
xpos 730
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{1.641023397 -0.3248033226 -0.2364246994}
{-0.6636629701 1.615331769 0.01675636508}
{0.01172191743 -0.008284457959 0.9883947968}
}
name ColorMatrix21
label "XYZ to ACEScg"
xpos 620
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{2.402741432 -0.8974840641 -0.3880533576}
{-0.8325796723 1.769231915 0.02371272631}
{0.03882339597 -0.08249972761 1.036368608}
}
name ColorMatrix15
label "XYZ to P3D60"
xpos 510
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{2.725393534 -1.018002748 -0.4401631057}
{-0.795167923 1.689731717 0.02264718339}
{0.04124190658 -0.0876390487 1.100929499}
}
name ColorMatrix19
label "XYZ to P3DCI"
xpos 400
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{2.493496418 -0.9313833117 -0.4027107358}
{-0.8294888139 1.762663841 0.02362467349}
{0.03584583849 -0.07617240399 0.9568845034}
}
name ColorMatrix17
label "XYZ to P3D65"
xpos 290
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{0.6954522133 0.1406786889 0.163869068}
{0.04479461163 0.8596711159 0.09553432465}
{-0.005525866989 0.004025223665 1.001500726}
}
name ColorMatrix12
label "XYZ to Rec2020"
xpos 180
ypos -136
}
push $Nc8c458e0
ColorMatrix {
matrix {
{3.240970135 -1.537383318 -0.4986107945}
{-0.9692437053 1.875967622 0.04155509174}
{0.0556300357 -0.2039768547 1.056971431}
}
name ColorMatrix2
label "XYZ to Rec709"
xpos 70
ypos -136
}
Switch {
inputs 8
which {{parent.limiting_pri}}
name limiting_primary_switch
xpos -40
ypos -34
}
Clamp {
channels rgb
name clamp_f3
label "Clip any values outside the limiting primaries"
xpos -40
ypos 56
}
Dot {
name Dot2
label " Convert limited RGB to XYZ"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -6
ypos 162
}
set N6f64f440 [stack 0]
push $N6f64f440
ColorMatrix {
matrix {
{0.9525524378 0 9.367863095e-05}
{0.3439664543 0.7281661034 -0.07213255018}
{-3.863927134e-08 0 1.008825183}
}
name ColorMatrix4
label "ACES to XYZ"
xpos 730
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.6624541879 0.1340042055 0.1561876982}
{0.2722287476 0.6740817428 0.05368951708}
{-0.005574660841 0.004060741514 1.010339141}
}
name ColorMatrix20
label "ACEScg to XYZ"
xpos 620
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.5049495697 0.2646814585 0.1830150485}
{0.237623319 0.6891706586 0.07320601493}
{0 0.0449459292 0.9638792276}
}
name ColorMatrix13
label "P3D60 to XYZ"
xpos 510
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.4451698363 0.2771343887 0.1722826511}
{0.209491685 0.7215952873 0.06891305745}
{0 0.04706057906 0.9073553085}
}
name ColorMatrix18
label "P3DCI to XYZ"
xpos 400
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.4865709841 0.2656676769 0.1982172877}
{0.2289745659 0.6917385459 0.07928691059}
{0 0.04511339962 1.043944359}
}
name ColorMatrix16
label "P3D65 to XYZ"
xpos 290
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.6369580626 0.1446169019 0.1688809693}
{0.2627002299 0.6779980659 0.05930171534}
{0 0.0280726999 1.060985088}
}
name ColorMatrix3
label "Rec2020 to XYZ"
xpos 180
ypos 224
}
push $N6f64f440
ColorMatrix {
matrix {
{0.4123907983 0.3575843275 0.180480808}
{0.2126390189 0.7151686549 0.07219231874}
{0.01933082007 0.1191947311 0.950532198}
}
name ColorMatrix1
label "Rec709 to XYZ"
xpos 70
ypos 224
}
Switch {
inputs 8
which {{parent.limiting_pri}}
name limiting_primary_switch1
xpos -40
ypos 326
}
Output {
name Output
xpos -40
ypos 446
}
end_group
Group {
name XYZ_2_DISPLAY_PRI
label "CIE XYZ to display encoding primaries"
xpos -1250
ypos 1976
addUserKnob {20 XYZ_2_DISPLAY_PRI_tab l XYZ_2_DISPLAY_PRI}
addUserKnob {4 display_pri l "display pri" M {Rec709 Rec2020 P3D65 P3DCI P3D60 ACEScg ACES XYZ}}
display_pri {{parent.display_pri}}
}
Input {
inputs 0
name Input
xpos -40
ypos -298
}
Dot {
name Dot1
label " XYZ to display primaries"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -6
ypos -198
}
set Nb6b388e0 [stack 0]
push $Nb6b388e0
ColorMatrix {
matrix {
{1.049811006 0 -9.748453158e-05}
{-0.4959030151 1.373313069 0.09824004024}
{4.020908051e-08 0 0.9912520051}
}
name ColorMatrix3
label "XYZ to ACES"
xpos 730
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{1.641023397 -0.3248033226 -0.2364246994}
{-0.6636629701 1.615331769 0.01675636508}
{0.01172191743 -0.008284457959 0.9883947968}
}
name ColorMatrix21
label "XYZ to ACEScg"
xpos 620
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{2.402741432 -0.8974840641 -0.3880533576}
{-0.8325796723 1.769231915 0.02371272631}
{0.03882339597 -0.08249972761 1.036368608}
}
name ColorMatrix15
label "XYZ to P3D60"
xpos 510
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{2.725393534 -1.018002748 -0.4401631057}
{-0.795167923 1.689731717 0.02264718339}
{0.04124190658 -0.0876390487 1.100929499}
}
name ColorMatrix19
label "XYZ to P3DCI"
xpos 400
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{2.493496418 -0.9313833117 -0.4027107358}
{-0.8294888139 1.762663841 0.02362467349}
{0.03584583849 -0.07617240399 0.9568845034}
}
name ColorMatrix17
label "XYZ to P3D65"
xpos 290
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{1.71665132 -0.3556708097 -0.2533662617}
{-0.6666844487 1.616481304 0.01576855592}
{0.01763986237 -0.04277062416 0.9421030879}
}
name ColorMatrix12
label "XYZ to Rec2020"
xpos 180
ypos -136
}
push $Nb6b388e0
ColorMatrix {
matrix {
{3.240970135 -1.537383318 -0.4986107945}
{-0.9692437053 1.875967622 0.04155509174}
{0.0556300357 -0.2039768547 1.056971431}
}
name ColorMatrix2
label "XYZ to Rec709"
xpos 70
ypos -136
}
Switch {
inputs 8
which {{parent.display_pri}}
name limiting_primary_switch
xpos -40
ypos -34
}
Output {
name Output
xpos -40
ypos 86
}
end_group
Clamp {
channels rgb
name clamp_f3_all
xpos -1250
ypos 2164
}
Dot {
name Dot1
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -1216
ypos 2514
}
set Nbd077910 [stack 0]
push $Nbd077910
Dot {
name Dot3
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -886
ypos 2514
}
set N93e8a0a0 [stack 0]
Dot {
name Dot4
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -666
ypos 2514
}
set Nce154af0 [stack 0]
Dot {
name Dot6
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -446
ypos 2514
}
set N1bde4160 [stack 0]
Dot {
name Dot18
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -226
ypos 2514
}
set Nd416b610 [stack 0]
Dot {
name Dot20
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos -6
ypos 2514
}
set Nd7bfb470 [stack 0]
Dot {
name Dot25
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 214
ypos 2514
}
set N99b88500 [stack 0]
Dot {
name Dot24
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 654
ypos 2514
}
Dot {
name Dot2
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 654
ypos 2610
}
set N1859d330 [stack 0]
Expression {
expr0 "r * (Ymax - Ymin) + Ymin"
expr1 "g * (Ymax - Ymin) + Ymin"
expr2 "b * (Ymax - Ymin) + Ymin"
name linCV_2_Y_f3_hdr
label "stretch_black = True"
xpos 510
ypos 2672
addUserKnob {20 Luminance}
addUserKnob {7 Ymin R 0.0001 0.02}
addUserKnob {7 Ymax R 48 10000}
Ymax {{parent.lum.2}}
}
push $N1859d330
Expression {
expr0 "r * (Ymax - Ymin) + Ymin"
expr1 "g * (Ymax - Ymin) + Ymin"
expr2 "b * (Ymax - Ymin) + Ymin"
name linCV_2_Y_f3_hdr2
label "stretch_black = False"
xpos 620
ypos 2672
addUserKnob {20 Luminance}
addUserKnob {7 Ymin R 0.0001 0.02}
Ymin {{parent.lum.0}}
addUserKnob {7 Ymax R 48 10000}
Ymax {{parent.lum.2}}
}
Switch {
inputs 2
which {{parent.stretch_black}}
name StretchBlacks_Switch
xpos 620
ypos 2750
}
Clamp {
channels rgb
maximum 65535
name clamp_f3__
xpos 620
ypos 2822
}
Expression {
temp_name0 Lm_r
temp_expr0 "pow((r / pq_C), pq_m1)"
temp_name1 Lm_g
temp_expr1 "pow((g / pq_C), pq_m1)"
temp_name2 Lm_b
temp_expr2 "pow((b / pq_C), pq_m1)"
expr0 "pow(( pq_c1 + pq_c2 * Lm_r ) / ( 1.0 + pq_c3 * Lm_r ), pq_m2)"
expr1 "pow(( pq_c1 + pq_c2 * Lm_g ) / ( 1.0 + pq_c3 * Lm_g ), pq_m2)"
expr2 "pow(( pq_c1 + pq_c2 * Lm_b ) / ( 1.0 + pq_c3 * Lm_b ), pq_m2)"
name Y_2_ST2084_
label "ACESlib.OutputTransforms.ctl : 243 \nACESlib.Utilities_Color.ctl : 425"
xpos 620
ypos 2882
addUserKnob {20 SMPTE_ST2084-2014_Constants_tab l "Constants from SMPTE ST 2084-2014"}
addUserKnob {7 pq_m1 t " ( 2610.0 / 4096.0 ) / 4.0;" +DISABLED R 0 100}
pq_m1 0.1593017578
addUserKnob {7 pq_m2 t " ( 2523.0 / 4096.0 ) * 128.0;" +DISABLED R 0 100}
pq_m2 78.84375
addUserKnob {7 pq_c1 t " 3424.0 / 4096.0 or pq_c3 - pq_c2 + 1.0;" +DISABLED R 0 100}
pq_c1 0.8359375
addUserKnob {7 pq_c2 t " ( 2413.0 / 4096.0 ) * 32.0;" +DISABLED R 0 100}
pq_c2 18.8515625
addUserKnob {7 pq_c3 t " ( 2392.0 / 4096.0 ) * 32.0;" +DISABLED R 0 100}
pq_c3 18.6875
addUserKnob {7 pq_C +DISABLED R 0 100}
pq_C 10000
}
set Na07f7510 [stack 0]
Dot {
name Dot5
label " "
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 984
ypos 2514
}
Expression {
temp_name0 Np_r
temp_expr0 "pow( r, 1.0 / pq_m2 )"
temp_name1 Np_g
temp_expr1 "pow( g, 1.0 / pq_m2 )"
temp_name2 Np_b
temp_expr2 "pow( b, 1.0 / pq_m2 )"
expr0 "r < 0 ? 0 : pow((Np_r - pq_c1) / ( pq_c2 - pq_c3 * Np_r ), 1.0/pq_m1) * pq_C"
expr1 "g < 0 ? 0 : pow((Np_g - pq_c1) / ( pq_c2 - pq_c3 * Np_g ), 1.0/pq_m1) * pq_C"
expr2 "b < 0 ? 0 : pow((Np_b - pq_c1) / ( pq_c2 - pq_c3 * Np_b ), 1.0/pq_m1) * pq_C"
name ST2084_2_Y_f3_
label "ACESlib.Utilities_Color.ctl : 408\n// Converts from the non-linear perceptually quantized space to linear cd/m^2"
xpos 950
ypos 2618
addUserKnob {20 SMPTE_ST2084-2014_Constants_tab l "Constants from SMPTE ST 2084-2014"}
addUserKnob {7 pq_m1 t " ( 2610.0 / 4096.0 ) / 4.0;" +DISABLED R 0 100}
pq_m1 0.1593017578
addUserKnob {7 pq_m2 t " ( 2523.0 / 4096.0 ) * 128.0;" +DISABLED R 0 100}
pq_m2 78.84375
addUserKnob {7 pq_c1 t " 3424.0 / 4096.0 or pq_c3 - pq_c2 + 1.0;" +DISABLED R 0 100}
pq_c1 0.8359375
addUserKnob {7 pq_c2 t " ( 2413.0 / 4096.0 ) * 32.0;" +DISABLED R 0 100}
pq_c2 18.8515625
addUserKnob {7 pq_c3 t " ( 2392.0 / 4096.0 ) * 32.0;" +DISABLED R 0 100}
pq_c3 18.6875
addUserKnob {7 pq_C +DISABLED R 0 100}
pq_C 10000
}
Expression {
temp_name0 Y_d
temp_expr0 "0.2627*r + 0.6780*g + 0.0593*b"
expr0 "Y_d == 0 ? 0 : pow( (Y_d-c_beta)/c_alpha, (1-c_gamma)/c_gamma) * ((r-c_beta)/c_alpha)"
expr1 "Y_d == 0 ? 0 : pow( (Y_d-c_beta)/c_alpha, (1-c_gamma)/c_gamma) * ((g-c_beta)/c_alpha)"
expr2 "Y_d == 0 ? 0 : pow( (Y_d-c_beta)/c_alpha, (1-c_gamma)/c_gamma) * ((b-c_beta)/c_alpha)"
name ST2084_2_HLG_1000nits_f3_3
label "ACESlib.Utilities_Color.ctl : 469\n// HLG Inverse EOTF (i.e. HLG inverse OOTF followed by the HLG OETF)\n// HLG Inverse OOTF (display linear to scene linear)"
xpos 950
ypos 2732
addUserKnob {20 Constants_tab l Constants}
addUserKnob {7 L_w +DISABLED}
L_w 1000
addUserKnob {7 L_b +DISABLED}
addUserKnob {7 c_alpha +DISABLED}
c_alpha {{L_w-L_b}}
addUserKnob {7 c_beta +DISABLED}
c_beta {{L_b}}
addUserKnob {7 c_gamma +DISABLED}
c_gamma 1.2
}
Expression {
channel0 {rgba.red -rgba.green -rgba.blue none}
expr0 "r <= 1.0/12 ? sqrt(3.0*r) : c_a * log(12.0 * r - c_b) + c_c"
expr1 "g <= 1.0/12 ? sqrt(3.0*g) : c_a * log(12.0 * g- c_b) + c_c"
expr2 "b <= 1.0/12 ? sqrt(3.0*b) : c_a * log(12.0 * b - c_b) + c_c"
name ST2084_2_HLG_1000nits_f3_
label "ACESlib.Utilities_Color.ctl : 493\n// HLG OETF (scene linear to non-linear signal value)"
xpos 950
ypos 2834
addUserKnob {20 Constants_tab l Constants}
addUserKnob {7 c_a +DISABLED}
c_a 0.17883277
addUserKnob {7 c_b t 1.-4.*a +DISABLED}
c_b 0.28466892
addUserKnob {7 c_c t 0.5-a*log(4.*a) +DISABLED}
c_c 0.55991073
}
Dot {
name Dot17
label " HLG"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 984
ypos 2970
}
push $Na07f7510
Dot {
name Dot27
label " PQ"
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xa5a5a501
xpos 654
ypos 2970
}
push $N99b88500
Expression {
expr0 "pow( (48./52.37) * r, 1./2.6)"
expr1 "pow( (48./52.37) * g, 1./2.6)"
expr2 "pow( (48./52.37) * b, 1./2.6)"
expr3 1
name dcdm_encode
xpos 180
ypos 2702
}
push $Nd7bfb470
Expression {
expr0 pow(r,1/gamma)
expr1 pow(g,1/gamma)
expr2 pow(b,1/gamma)
name pow_f3_gamma_26_
label "ACESlib.Utilities_Color.ctl : 260\n// Gamma 2.6"
xpos -40
ypos 2690
addUserKnob {20 Gamma_tab l Gamma}
addUserKnob {7 gamma R 0 4}
gamma 2.6
}
push $Nd416b610
Expression {
expr0 pow(r,1/gamma)
expr1 pow(g,1/gamma)
expr2 pow(b,1/gamma)
name pow_f3_gamma_24_
label "ACESlib.Utilities_Color.ctl : 260\n// Gamma 2.4"
xpos -260
ypos 2690
addUserKnob {20 Gamma_tab l Gamma}
addUserKnob {7 gamma R 0 4}
gamma 2.4
}
push $N1bde4160
Expression {
expr0 pow(r,1/gamma)
expr1 pow(g,1/gamma)
expr2 pow(b,1/gamma)
name pow_f3_gamma_22_
label "ACESlib.Utilities_Color.ctl : 260\n// Gamma 2.2"
xpos -480
ypos 2690
addUserKnob {20 Gamma_tab l Gamma}
addUserKnob {7 gamma R 0 4}
gamma 2.2
}
push $Nce154af0
Expression {
temp_name0 c_a
temp_expr0 "pow( pow( Lw, 1./gamma) - pow( Lb, 1./gamma), gamma)"
temp_name1 c_b
temp_expr1 "pow( Lb, 1./gamma) / ( pow( Lw, 1./gamma) - pow( Lb, 1./gamma))"
expr0 "pow( max( r / c_a, 0.), 1.0/gamma) - c_b"
expr1 "pow( max( g / c_a, 0.), 1.0/gamma) - c_b"
expr2 "pow( max( b / c_a, 0.), 1.0/gamma) - c_b"
name bt1886_r_f3
label "ACESlib.Utilities_Color.ctl : 301\n// The reference EOTF specified in Rec. ITU-R BT.1886\n// L = a(max\[(V+b),0])^g"
xpos -700
ypos 2684
addUserKnob {20 Luminance}
addUserKnob {7 Lw R 48 10000}
Lw 1
addUserKnob {7 Lb R 0.0001 0.02}
addUserKnob {7 gamma R 1 4}
gamma 2.4
}
push $N93e8a0a0
Expression {
temp_name0 yb
temp_expr0 "pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma)"
temp_name1 rs
temp_expr1 "pow( ( gamma - 1.0) / offs, gamma - 1.0) * pow( ( 1.0 + offs) / gamma, gamma)"
expr0 "r >= yb ? ( 1.0 + offs) * pow( r, 1.0 / gamma) - offs : r * rs"
expr1 "g >= yb ? ( 1.0 + offs) * pow( g, 1.0 / gamma) - offs : g * rs"
expr2 "b >= yb ? ( 1.0 + offs) * pow( b, 1.0 / gamma) - offs : b * rs"
name moncurve_r_f3_
label "ACESlib.Utilities_Color.ctl : 260\nmoncurve_r with gamma of 2.4 and offset of 0.055 matches the EOTF found in IEC 61966-2-1:1999 (sRGB)"
xpos -920
ypos 2690
addUserKnob {20 Luminance}
addUserKnob {7 gamma R 0 4}
gamma 2.4
addUserKnob {7 offs}
offs 0.055
}
Switch {
inputs 10
which {{parent.eotf}}
name EOTF_Switch
xpos -1250
ypos 2966
}
Expression {
temp_name0 REFBLACK
temp_expr0 "64 / 1023"
temp_name1 REFWHITE
temp_expr1 "940 / 1023"
expr0 "r * ( REFWHITE - REFBLACK) + REFBLACK"
expr1 "g * ( REFWHITE - REFBLACK) + REFBLACK"
expr2 "b * ( REFWHITE - REFBLACK) + REFBLACK"
name fullRange_to_smpteRange_f3_
label "ACESlib.OutputTransforms.ctl : 216"
xpos -1250
ypos 3224
disable {{!parent.legal_range}}
}
Output {
name Output
xpos -1250
ypos 3446
}
StickyNote {
inputs 0
name StickyNote1
tile_color 0x535a61ff
label "\n<b>ACESlib.RRT_Common.ctl : 135</b>\n<pre>\nfloat\[3] rrt_sweeteners( float in\[3])\n\{\n float aces\[3] = in;\n \n // --- Glow module --- //\n float saturation = rgb_2_saturation( aces);\n float ycIn = rgb_2_yc( aces);\n float s = sigmoid_shaper( (saturation - 0.4) / 0.2);\n float addedGlow = 1. + glow_fwd( ycIn, RRT_GLOW_GAIN * s, RRT_GLOW_MID);\n\n aces = mult_f_f3( addedGlow, aces);\n\n // --- Red modifier --- //\n float hue = rgb_2_hue( aces);\n float centeredHue = center_hue( hue, RRT_RED_HUE);\n float hueWeight = cubic_basis_shaper( centeredHue, RRT_RED_WIDTH);\n\n aces\[0] = aces\[0] + hueWeight * saturation * (RRT_RED_PIVOT - aces\[0]) * (1. - RRT_RED_SCALE);\n\n // --- ACES to RGB rendering space --- //\n aces = clamp_f3( aces, 0., HALF_POS_INF);\n float rgbPre\[3] = mult_f3_f44( aces, AP0_2_AP1_MAT);\n rgbPre = clamp_f3( rgbPre, 0., HALF_MAX);\n \n // --- Global desaturation --- //\n rgbPre = mult_f3_f33( rgbPre, RRT_SAT_MAT);\n return rgbPre;\n\}\n\n\n\n"
note_font_size 10
xpos -825
ypos -1204
}
StickyNote {
inputs 0
name StickyNote2
tile_color 0x535a61ff
label "\n\n<b>ACESlib.SSTS.ctl : 163</b><pre>float ssts\n( \n varying float x,\n varying TsParams C\n)\n\{\n const int N_KNOTS_LOW = 4;\n const int N_KNOTS_HIGH = 4;\n\n // Check for negatives or zero before taking the log. If negative or zero,\n // set to HALF_MIN.\n float logx = log10( max(x, HALF_MIN )); \n\n float logy;\n\n if ( logx <= log10(C.Min.x) ) \{ \n\n logy = logx * C.Min.slope + ( log10(C.Min.y) - C.Min.slope * log10(C.Min.x) );\n\n \} else if (( logx > log10(C.Min.x) ) && ( logx < log10(C.Mid.x) )) \{\n\n float knot_coord = (N_KNOTS_LOW-1) * (logx-log10(C.Min.x))/(log10(C.Mid.x)-log10(C.Min.x));\n int j = knot_coord;\n float t = knot_coord - j;\n\n float cf\[ 3] = \{ C.coefsLow\[ j], C.coefsLow\[ j + 1], C.coefsLow\[ j + 2]\};\n\n float monomials\[ 3] = \{ t * t, t, 1. \};\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M1));\n\n \} else if (( logx >= log10(C.Mid.x) ) && ( logx < log10(C.Max.x) )) \{\n\n float knot_coord = (N_KNOTS_HIGH-1) * (logx-log10(C.Mid.x))/(log10(C.Max.x)-log10(C.Mid.x));\n int j = knot_coord;\n float t = knot_coord - j;\n\n float cf\[ 3] = \{ C.coefsHigh\[ j], C.coefsHigh\[ j + 1], C.coefsHigh\[ j + 2]\}; \n\n float monomials\[ 3] = \{ t * t, t, 1. \};\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M1));\n\n \} else \{ //if ( logIn >= log10(C.Max.x) ) \{ \n\n logy = logx * C.Max.slope + ( log10(C.Max.y) - C.Max.slope * log10(C.Max.x) );\n\n \}\n\n return pow10(logy);\n\n\}"
note_font_size 10
xpos -830
ypos -664
}
StickyNote {
inputs 0
name StickyNote3
tile_color 0x535a61ff
label "\n\n<b>ACESlib.Tonescales.ctl : 271</b><pre>float segmented_spline_c9_fwd\n ( \n varying float x,\n varying SegmentedSplineParams_c9 C = ODT_48nits\n )\n\{ \n const int N_KNOTS_LOW = 8;\n const int N_KNOTS_HIGH = 8;\n\n // Check for negatives or zero before taking the log. If negative or zero,\n // set to HALF_MIN.\n float logx = log10( max(x, HALF_MIN )); \n\n float logy;\n\n if ( logx <= log10(C.minPoint.x) ) \{ \n\n logy = logx * C.slopeLow + ( log10(C.minPoint.y) - C.slopeLow * log10(C.minPoint.x) );\n\n \} else if (( logx > log10(C.minPoint.x) ) && ( logx < log10(C.midPoint.x) )) \{\n\n float knot_coord = (N_KNOTS_LOW-1) * (logx-log10(C.minPoint.x))/(log10(C.midPoint.x)-log10(C.minPoint.x));\n int j = knot_coord;\n float t = knot_coord - j;\n\n float cf\[ 3] = \{ C.coefsLow\[ j], C.coefsLow\[ j + 1], C.coefsLow\[ j + 2]\};\n \n float monomials\[ 3] = \{ t * t, t, 1. \};\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M));\n\n \} else if (( logx >= log10(C.midPoint.x) ) && ( logx < log10(C.maxPoint.x) )) \{\n\n float knot_coord = (N_KNOTS_HIGH-1) * (logx-log10(C.midPoint.x))/(log10(C.maxPoint.x)-log10(C.midPoint.x));\n int j = knot_coord;\n float t = knot_coord - j;\n\n float cf\[ 3] = \{ C.coefsHigh\[ j], C.coefsHigh\[ j + 1], C.coefsHigh\[ j + 2]\}; \n\n float monomials\[ 3] = \{ t * t, t, 1. \};\n logy = dot_f3_f3( monomials, mult_f3_f33( cf, M));\n\n \} else \{ //if ( logIn >= log10(C.maxPoint.x) ) \{ \n\n logy = logx * C.slopeHigh + ( log10(C.maxPoint.y) - C.slopeHigh * log10(C.maxPoint.x) );\n\n \}\n\n return pow10(logy);\n \n\}"
note_font_size 10
xpos -200
ypos -660
}
end_group
Switch {
inputs 2
which {{t==5}}
name Switch6
note_font Helvetica
selected true
xpos 8650
ypos 8727
}
Reformat {
type scale
scale 2
name Reformat5
note_font Helvetica
selected true
xpos 8650
ypos 8770
}
Dot {
name Dot64
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 8684
ypos 8802
}
Dot {
name Dot65
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 8794
ypos 8802
}
set Na8080390 [stack 0]
Dot {
name Dot66
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 8904
ypos 8802
}
set N5054dc10 [stack 0]
Dot {
name Dot67
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 9014
ypos 8802
}
set Na4582b40 [stack 0]
FrameHold {
first_frame 3
name FrameHold3
note_font Helvetica
selected true
xpos 8980
ypos 8866
}
Write {
file ./images/arri_ludwigstrabe_purple_highlight_fringe_aces_rec709_tanh_thr-0.5_lim-0.2.jpeg
raw true
file_type jpeg
_jpeg_quality 0.9
_jpeg_sub_sampling 4:2:2
checkHashOnRead false
version 2
name Write4
note_font Helvetica
selected true
xpos 8980
ypos 8933
}
push $Na4582b40
Dot {
name Dot68
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 9124
ypos 8802
}
set N23bf0960 [stack 0]
FrameHold {
first_frame 4
name FrameHold4
note_font Helvetica
selected true
xpos 9090
ypos 8866
}
Write {
file ./images/arri_ludwigstrabe_purple_highlight_fringe_aces_rec709_reinhard_thr-0.3_lim-0.2.jpeg
raw true
file_type jpeg
_jpeg_quality 0.9
_jpeg_sub_sampling 4:2:2
checkHashOnRead false
version 2
name Write5
note_font Helvetica
selected true
xpos 9090
ypos 8933
}
push $N23bf0960
Dot {
name Dot69
note_font "Helvetica Bold"
note_font_size 24
note_font_color 0xff
selected true
xpos 9234
ypos 8802
}
FrameHold {
first_frame 5
name FrameHold5
note_font Helvetica
selected true
xpos 9200
ypos 8866
}
Write {
file ./images/arri_ludwigstrabe_purple_highlight_fringe_arri_r709_d65_r1886.jpeg
raw true
file_type jpeg
_jpeg_quality 0.9
_jpeg_sub_sampling 4:2:2
checkHashOnRead false
version 2
name Write6
note_font Helvetica
selected true
xpos 9200
ypos 8933
}
push $Na8080390
FrameHold {
first_frame 1
name FrameHold1
note_font Helvetica
selected true
xpos 8760
ypos 8866
}
Write {
file ./images/arri_ludwigstrabe_purple_highlight_fringe_aces_rec709.jpeg
raw true
file_type jpeg
_jpeg_quality 0.9
_jpeg_sub_sampling 4:2:2
checkHashOnRead false
version 2
name Write1
note_font Helvetica
selected true
xpos 8760
ypos 8933
}
push $N5054dc10
FrameHold {
first_frame 2
name FrameHold2
note_font Helvetica
selected true
xpos 8870
ypos 8866
}
Write {
file ./images/arri_ludwigstrabe_purple_highlight_fringe_aces_rec709_tanh_thr-0.2_lim-0.2.jpeg
raw true
file_type jpeg
_jpeg_quality 0.9
_jpeg_sub_sampling 4:2:2
checkHashOnRead false
version 2
name Write3
note_font Helvetica
selected true
xpos 8870
ypos 8933
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment