set cut_paste_input [stack 0] push $cut_paste_input Group { name ReGrain tile_color 0x7f7f7fff addUserKnob {20 Params} addUserKnob {26 out_label l "output " T ""} addUserKnob {83 out l " " t "
Output mode
regrain: apply grain to input. where diff = 1, plate grain will be used. Where diff = 0, grain plate will be used. Adjust diff threshold to set hardness of matte.
diff: show diff between input and degrain as red overlay.
ngrain: output grain normalized by analysis. Useful for creating grain plates.
grain: final adapted grain used for applying regrain to denoised comp, mixed with grain plate if used." -STARTLINE M {regrain diff ngrain grain}} addUserKnob {41 dfth l "diff thresh" t "threshold for difference between comp and degrain" T MergeDifference.mn} addUserKnob {20 sample_grp l "sampling parameters (expert)" t "parameters for grain intensity analysis. defaults should be good for most cases." n 1} sample_grp 0 addUserKnob {41 lg l log T lin_to_log.lg} addUserKnob {41 mn_e l "min exp" T extract.mn_e} addUserKnob {41 mx_e l "max exp" T extract.mx_e} addUserKnob {41 sw l "sample step" T extract.sw} addUserKnob {41 samples l "time samples" t "Number of frames to analyze in input framerange" T FrameHold1.samples} addUserKnob {41 tg l target T extract.tg} addUserKnob {26 ""} addUserKnob {41 p l position t "sample position" T extract.p} addUserKnob {6 prev l "preview sample" t "Preview sample slice at current exposure position. \nR = total grain intensity\nG = degrain\nB = pixel contribution" +STARTLINE} addUserKnob {6 disable_grainplate l "disable grainplate" t "Toggle off grain plate input so that plate grain is used everywhere. Useful for troubleshooting." -STARTLINE} addUserKnob {20 endGroup n -1} addUserKnob {22 analyze l "Analyze Grain Response" t "Analyze grain response curve from dgrn and plt inputs." T "import nuke\nimport math\nimport re\n\ndef arange(start, end, step):\n while start <= end:\n yield float(start)\n start += step\n\ndef ln2lg(x):\n lnlg = nuke.toNode('lin_to_log')\n mn = lnlg\['mn'].getValue()\n mx = lnlg\['mx'].getValue()\n sp = lnlg\['sp'].getValue()\n lo = (math.log2(sp/0.18)-mn)/(mx-mn)\n ls = sp*(mx-mn)*math.log(2)\n if x >= sp:\n return (math.log2(x/0.18)-mn)/(mx-mn)\n else:\n return (x-sp)/ls+lo\n\ndef analyze(node):\n with node:\n # get nodes for sampling\n ex = nuke.toNode('extract')\n sa = nuke.toNode('sample')\n ct = nuke.toNode('curvetool')\n # and their knob values we need\n ik = ct\['intensitydata']\n mn = ex\['mn_e'].getValue()\n mx = ex\['mx_e'].getValue()\n tg = ex\['tg'].getValue()\n sw = ex\['sw'].getValue()\n lg = node\['lg'].getValue()\n # sample frames are blended together, so it doesn't matter what frame we're on\n fr = nuke.frame()\n # get lut and reset it\n lut = nuke.toNode('LUT')\['lut']\n lut.fromScript('red \{curve\}\\ngreen \{curve\}\\nblue \{curve\}')\n chl = \['red', 'green', 'blue']\n # generate sample list in stops from middle grey\n samples = list(arange(mn, mx, sw))\n task = nuke.ProgressTask('Analysis In Progress:')\n\n for i, ch in enumerate(chl):\n sa\['ch'].setValue(i)\n ik.clearAnimated()\n # store previous sample\n pvy = 0\n for s in samples:\n if task.isCancelled():\n return\n task.setMessage('channel: \{0\}\\n sample: \{1\}'.format(chl\[i], s))\n # set sample to current position\n ex\['p'].setValue(s)\n # get sample values from curvetool\n nuke.execute(ct, fr, fr)\n v = ik.getValue()\n vn = v\[2] # alpha value for normalization\n if vn != 0:\n vy = (v\[0] / vn) / tg # normalize by target \n vx = v\[1] / vn\n if lg:\n vy = ln2lg(vy)\n vx = ln2lg(vx)\n # make sure sample values do not decrease\n if vy > pvy:\n lut.setValueAt(vy, vx, i+1)\n pvy = vy\n else:\n # skip if no samples at the exposure in image\n print('no samples at \{0\} stops'.format(s))\n \n ex\['p'].setValue(0)\n del task\n # continue first and last keyframes in lut\n lutc = re.sub(r'(x\\d+.\\d+ \\d+.\\d+)\[^.]*\}', r'C \\1\}', lut.toScript())\n lutc = re.sub(r'(\{curve )', r'\\1C ', lutc)\n lut.fromScript(lutc)\n\nanalyze(nuke.thisNode())" +STARTLINE} addUserKnob {41 lut l "" +STARTLINE T LUT.lut} addUserKnob {22 copy_lut l "Copy Curves to Selected" t "rg\['lut'].fromScript(node\['lut'].toScript())" T "n = nuke.thisNode()\nwith nuke.root():\n tg = nuke.selectedNode()\n if tg and 'lut' in tg.knobs():\n tg\['lut'].fromScript(n\['lut'].toScript())\n else:\n nuke.message('Please select a node with a lut knob')\n ck = \['mn', 'mx', 'lg']\n for k in ck:\n if k in tg.knobs():\n tg\[k].setValue(n\[k].getValue())" +STARTLINE} } BackdropNode { inputs 0 name BackdropNode1 tile_color 0x42424201 label "analyze grain" note_font Helvetica note_font_size 10 note_font_color 0xffffffff xpos -640 ypos -65 bdwidth 180 bdheight 322 z_order -10 } Input { inputs 0 name Inputplt label "\[value number]" xpos -370 ypos -208 number 2 } Dot { name Dot5 label " plate" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -336 ypos -150 } Reformat { type "to box" box_width {{Input.width}} box_height {{Input.height}} box_fixed true box_pixel_aspect {{Input.pixel_aspect}} pbb true name Reformat2 xpos -370 ypos -106 } FrameRange { first_frame {{FrameRange1.first_frame}} last_frame {{FrameRange1.last_frame}} time "" name FrameRange3 label "\[value first_frame]-\[value last_frame]" xpos -370 ypos -64 } set Na9cd1600 [stack 0] Input { inputs 0 name Inputdgrn label "\[value number]" xpos -260 ypos -208 number 1 } Dot { name Dot3 label " degrain" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -226 ypos -150 } Reformat { type "to box" box_width {{Input.width}} box_height {{Input.height}} box_fixed true box_pixel_aspect {{Input.pixel_aspect}} pbb true name Reformat1 xpos -260 ypos -106 } FrameRange { first_frame {{FrameRange1.first_frame}} last_frame {{FrameRange1.last_frame}} time "" name FrameRange2 label "\[value first_frame]-\[value last_frame]" xpos -260 ypos -64 } Dot { name Dot4 xpos -226 ypos -6 } set Naa49b200 [stack 0] MergeExpression { inputs 2 temp_name0 dg temp_expr0 ch==0?Br:ch==1?Bg:Bb temp_name1 pl temp_expr1 ch==0?Ar:ch==1?Ag:Ab temp_name2 gr temp_expr2 fabs(pl-dg) expr0 gr expr1 dg expr2 0 name sample xpos -590 ypos -10 addUserKnob {20 Params} addUserKnob {3 ch} ch 2 } Expression { temp_name3 xt temp_expr3 g>=mn&&g<=mx expr0 r*xt expr1 g*xt expr2 xt expr3 0 name extract xpos -590 ypos 38 addUserKnob {20 Params} addUserKnob {7 mn_e l "min exp" t "lowest sample position in stops from 0.18.\n\nif your comp is _very_ dark, you may need to lower this." R -10 0} mn_e -7 addUserKnob {7 mx_e l "max exp" t "highest sample position in stops from 0.18." R 0 10} mx_e 7 addUserKnob {7 p t "sample position in stops around 0.18\n" R -12 12} addUserKnob {7 sw t "step size in stops for each sample.\n\ne.g. 1 will do a sample analysis starting at position = min exp, at 1 stop increments to max exp" R 0 2} sw 1 addUserKnob {7 tg l target t "target grain intensity value it will be normalized to. \n\njust sets the base grain intensity level." R 0 0.1} tg 0.005 addUserKnob {7 mn} mn {{0.18*2**(p-sw/2)}} addUserKnob {7 mx} mx {{0.18*2**(p+sw/2)}} } FrameHold { first_frame {{input.first_frame+fstep*t}} name FrameHold1 xpos -590 ypos 80 addUserKnob {20 Params} addUserKnob {3 samples} samples 3 addUserKnob {7 fstep l step R 0 100} fstep {{(input.last_frame-input.first_frame)/samples}} } FrameBlend { channels rgb numframes 11 startframe 0 endframe {{input.samples}} userange true name FrameBlend2 xpos -590 ypos 134 } CurveTool { avgframes 0 channels rgba ROI {0 -6 {width x7 2104} {height x7 1136}} intensitydata {{curve x11 0} {curve x11 0} {curve x11 0} {curve x11 0}} name curvetool xpos -590 ypos 182 } Dot { name Dot10 xpos -556 ypos 690 } Input { inputs 0 name Inputdiff label "\[value number]" xpos -150 ypos -208 number 4 } Dot { name Dot15 xpos -116 ypos 66 } push $Naa49b200 Input { inputs 0 name Input label "\[value number]" xpos 70 ypos -208 } Dot { name Dot7 label " comp" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos 104 ypos -150 } FrameRange { first_frame {{fre?root.first_frame:input.first_frame}} last_frame {{fre?root.last_frame:input.last_frame}} time "" name FrameRange1 label "\[value first_frame]-\[value last_frame]" xpos 70 ypos -64 addUserKnob {20 Params} addUserKnob {6 fre +STARTLINE} fre {{input.first_frame==input.last_frame}} } set Naa474800 [stack 0] Dot { name Dot1 xpos 104 ypos -6 } set Naa474100 [stack 0] MergeExpression { inputs 2 temp_name0 df temp_expr0 max(fabs(Ar-Br),fabs(Ag-Bg),fabs(Ab-Bb)) channel0 {rgba.red -rgba.green -rgba.blue none} expr0 r expr1 g expr2 b expr3 clamp((mn-df)/(mx-mn)) name MergeDifference xpos -40 ypos -10 addUserKnob {20 Params} addUserKnob {7 fa l falloff R 0 0.1} addUserKnob {7 mn l "diff thresh" R 0 0.2} mn 0.05 addUserKnob {7 mx} mx {{mn+fa}} } MergeExpression { inputs 2 expr3 Aa name MergeExpression1 xpos -40 ypos 63 disable {{"!\[exists parent.input4]"}} } Fill { output rgb color {1 0 0 1} maskChannelInput rgba.alpha mix 0.3 name Fill1 xpos -40 ypos 128 } Dot { name Dot11 xpos -6 ypos 450 } set Naa451d00 [stack 0] push $Naa474100 Dot { name Dot9 xpos 104 ypos 282 } set Naa451600 [stack 0] Expression { temp_name0 lgr temp_expr0 LUT.lut.red(r>sp?(log(r/0.18)/log(2)-mn)/(mx-mn):(r-sp)/ls+lo) temp_name1 lgg temp_expr1 LUT.lut.green(g>sp?(log(g/0.18)/log(2)-mn)/(mx-mn):(g-sp)/ls+lo) temp_name2 lgb temp_expr2 LUT.lut.blue(b>sp?(log(b/0.18)/log(2)-mn)/(mx-mn):(b-sp)/ls+lo) expr0 lg?lgr>lo?0.18*2**(lgr*(mx-mn)+mn):ls*(lgr-lo)+sp:LUT.lut.red(r) expr1 lg?lgg>lo?0.18*2**(lgg*(mx-mn)+mn):ls*(lgg-lo)+sp:LUT.lut.green(g) expr2 lg?lgb>lo?0.18*2**(lgb*(mx-mn)+mn):ls*(lgb-lo)+sp:LUT.lut.blue(b) name lg2ApplyLUTlx2 xpos -150 ypos 279 addUserKnob {20 Params} addUserKnob {6 lg l log t "apply LUT in log encoding" +STARTLINE} lg {{parent.lin_to_log.lg}} addUserKnob {7 mn R -12 0} mn {{parent.lin_to_log.mn}} addUserKnob {7 mx R 0 12} mx {{parent.lin_to_log.mx}} addUserKnob {7 sp t "splice point"} sp {{parent.lin_to_log.sp}} addUserKnob {7 lo t "linear offset"} lo {{(log(sp/0.18)/log(2)-mn)/(mx-mn)}} addUserKnob {7 ls t "linear slope"} ls {{sp*(mx-mn)*log(2)}} } Dot { name Dot16 xpos -226 ypos 282 } set Naa450800 [stack 0] Input { inputs 0 name Inputgrn label "\[value number]" xpos -810 ypos -208 number 3 } Dot { name Dot6 label " grain plate" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -776 ypos -150 } Reformat { type "to box" box_width {{Input.width}} box_height {{Input.height}} box_fixed true box_pixel_aspect {{Input.pixel_aspect}} resize fill filter Lanczos4 pbb true name Reformat3 xpos -810 ypos -106 } TimeClip { time "" first {{input.first_frame}} before loop last {{input.last_frame}} after loop origset true name TimeClip1 xpos -810 ypos -64 } Merge2 { inputs 2 operation multiply bbox B output rgb name Merge1 xpos -810 ypos 278 } Dot { name Dot13 label " adapted grain plate" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -776 ypos 426 } Dot { name Dot2 xpos -776 ypos 522 } push $Naa450800 push $Naa49b200 Expression { temp_name0 lgr temp_expr0 LUT.lut.red(r>sp?(log(r/0.18)/log(2)-mn)/(mx-mn):(r-sp)/ls+lo) temp_name1 lgg temp_expr1 LUT.lut.green(g>sp?(log(g/0.18)/log(2)-mn)/(mx-mn):(g-sp)/ls+lo) temp_name2 lgb temp_expr2 LUT.lut.blue(b>sp?(log(b/0.18)/log(2)-mn)/(mx-mn):(b-sp)/ls+lo) expr0 lg?lgr>lo?0.18*2**(lgr*(mx-mn)+mn):ls*(lgr-lo)+sp:LUT.lut.red(r) expr1 lg?lgg>lo?0.18*2**(lgg*(mx-mn)+mn):ls*(lgg-lo)+sp:LUT.lut.green(g) expr2 lg?lgb>lo?0.18*2**(lgb*(mx-mn)+mn):ls*(lgb-lo)+sp:LUT.lut.blue(b) name lg2ApplyLUTlx1 xpos -260 ypos 135 addUserKnob {20 Params} addUserKnob {6 lg l log t "apply LUT in log encoding" +STARTLINE} lg {{parent.lin_to_log.lg}} addUserKnob {7 mn R -12 0} mn {{parent.lin_to_log.mn}} addUserKnob {7 mx R 0 12} mx {{parent.lin_to_log.mx}} addUserKnob {7 sp t "splice point"} sp {{parent.lin_to_log.sp}} addUserKnob {7 lo t "linear offset"} lo {{(log(sp/0.18)/log(2)-mn)/(mx-mn)}} addUserKnob {7 ls t "linear slope"} ls {{sp*(mx-mn)*log(2)}} } push $Naa49b200 push $Na9cd1600 Merge2 { inputs 2 operation from bbox B output rgb name MergeFrom xpos -370 ypos 38 } MergeExpression { inputs 2 expr0 Ar==0?0:Br/Ar expr1 Ag==0?0:Bg/Ag expr2 Ab==0?0:Bb/Ab name NormalizeGrain xpos -370 ypos 134 } Dot { name Dot12 label " normalized plate grain" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -336 ypos 234 } set Naa3eb900 [stack 0] Merge2 { inputs 2 operation multiply bbox B output rgb name Merge3 xpos -370 ypos 350 } Dot { name Dot8 label " adapted plate grain" note_font "Helvetica Bold" note_font_size 24 note_font_color 0xff xpos -336 ypos 426 } Keymix { inputs 3 channels rgb invertMask true bbox B name Keymix7 xpos -370 ypos 518 disable {{"disable_grainplate?1:!\[exists parent.input3]"}} } set Naa3ea400 [stack 0] Dot { name Dot14 xpos -336 ypos 618 } push $Naa3eb900 push $Naa451d00 push $Naa3ea400 push $Naa451600 Merge2 { inputs 2 operation plus bbox B output rgb name Merge2 xpos 70 ypos 518 } Switch { inputs 4 which {{out}} name Switch_out xpos 70 ypos 614 } Switch { inputs 2 which {{prev}} name Switch_prev xpos 70 ypos 686 } Output { name Output xpos 70 ypos 806 } push $Naa474800 Expression { expr0 r>sp?(log(r/0.18)/log(2)-mn)/(mx-mn):(r-sp)/ls+lo expr1 g>sp?(log(g/0.18)/log(2)-mn)/(mx-mn):(g-sp)/ls+lo expr2 b>sp?(log(b/0.18)/log(2)-mn)/(mx-mn):(b-sp)/ls+lo name lin_to_log xpos 180 ypos -57 disable {{!lg}} addUserKnob {20 Params} addUserKnob {6 lg l log t "use log encoding for LUT so values appear evenly distributed over stops" +STARTLINE} lg true addUserKnob {7 mn R -12 0} mn -8 addUserKnob {7 mx R 0 12} mx 7 addUserKnob {7 sp t "splice point"} sp {{2**-8}} addUserKnob {7 lo t "linear offset"} lo {{(log(sp/0.18)/log(2)-mn)/(mx-mn)}} addUserKnob {7 ls t "linear slope"} ls {{sp*(mx-mn)*log(2)}} } Sampler { lut {red {curve} green {curve} blue {curve}} name LUT xpos 180 ypos -34 } end_group