Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DasGrain.gimmick 46KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515
  1. set cut_paste_input [stack 0]
  2. version 12.2 v5
  3. push $cut_paste_input
  4. Group {
  5. name DegrainHelper
  6. help "The degrained plate has to be completely degrained.\n\nThe slider controls how much luminance grain will be present in the output."
  7. tile_color 0x7f7f7fff
  8. selected true
  9. xpos -152
  10. ypos 392
  11. addUserKnob {20 User}
  12. addUserKnob {7 luma_mix l "luminance degrain amount"}
  13. luma_mix 0.8
  14. }
  15. Input {
  16. inputs 0
  17. name PLATE
  18. xpos -590
  19. ypos -250
  20. number 1
  21. }
  22. Colorspace {
  23. colorspace_out YCbCr
  24. name Colorspace2
  25. xpos -590
  26. ypos -178
  27. }
  28. Dot {
  29. name Dot25
  30. xpos -556
  31. ypos -126
  32. }
  33. Input {
  34. inputs 0
  35. name DEGRAINED_PLATE
  36. xpos -700
  37. ypos -250
  38. }
  39. Colorspace {
  40. colorspace_out YCbCr
  41. name Colorspace1
  42. xpos -700
  43. ypos -178
  44. }
  45. Copy {
  46. inputs 2
  47. from0 rgba.red
  48. to0 rgba.red
  49. mix {{1-parent.luma_mix}}
  50. name Copy1
  51. xpos -700
  52. ypos -136
  53. }
  54. Colorspace {
  55. colorspace_in YCbCr
  56. name Colorspace3
  57. xpos -700
  58. ypos -82
  59. }
  60. Output {
  61. name Output1
  62. xpos -700
  63. ypos -10
  64. }
  65. end_group
  66. push $cut_paste_input
  67. Group {
  68. name DasGrain
  69. help "DasGrain makes regraining as simple as clicking a few buttons.\n\nFollow the steps in the Help tab and you'll have a perfect regrain in no time!"
  70. onCreate "import random\n\ntestimonials = \[\n \"Such an elegant solution, love it!\",\n \"Your gizmo is beyond expectation\",\n \"Totally awesome!\",\n \"DasGrain is officially the best thing ever\",\n \"It's really working!\",\n \"Das bringt Tr&auml;nen in meine Augen\",\n \"DasGrain is the salvation we waited for\",\n \"I save a lot of time, and definitely my nerves :)\",\n \"It's alright\",\n \"My new favourite node, thanks!<br>Having said that, ...\"\n ]\n\nnode = nuke.thisNode()\nnode\['testimonial'].setValue('<br><br><br><i>&laquo;%s&raquo;</i><br>&mdash; anonymous<br><br>' % random.choice(testimonials))\nnode\['box'].setFlag(nuke.NO_ANIMATION)"
  71. knobChanged "n = nuke.thisNode()\nk = nuke.thisKnob()\n\nif k.name() == 'box':\n this_frame = nuke.frame()\n n\['sample_frame'].setValue(this_frame)\n\nif k.name() == 'scatter':\n n\['divider04'].setVisible(k.value() == False)\n n\['divider05'].setVisible(k.value() == True)"
  72. tile_color 0x7f7f7fff
  73. label "v1.8 | 2021-03-07"
  74. selected true
  75. xpos -152
  76. ypos 475
  77. addUserKnob {20 DasGrain_tab l DasGrain}
  78. addUserKnob {41 output t "<strong>regrained comp</strong> it is what it sais\n<strong>plate grain</strong> plate minus degrained plate\n<strong>normalised grain</strong> check if the normalization worked. It should be as even as possible. This is what you want to output if you want to prerender a grain plate. Later you can plug it into the <i>external grain</i> input of another DasGrain\n<strong>adapted grain</strong> check if the adaptation worked. Output this if you want to further manipulate the grain (who knows what the sup is gonna come up with...). After, simply plus it to your comp (at that point the comp has to be in the <i>camera</i> colorspace, as set in the <i>Analyze</i> tab).\n<strong>grain QC</strong> check if voronoi seams are visible (&#8594; edgeblend), or the scattered grain looks different to the original plate grain (&#8594; maybe bad sample area or wrong luminance degrain amount)" T Output.output}
  79. addUserKnob {4 meta l "metadata from" t "Chances are you want to use the metadata from the plate, but who am I to assume :)" M {COMP PLATE}}
  80. addUserKnob {26 spacer01_1 l " " T " "}
  81. addUserKnob {20 GrainGroupBegin l "" +STARTLINE n -2}
  82. addUserKnob {20 Analyze_tab l Analyze}
  83. addUserKnob {26 text l <strong>Colorspace}
  84. addUserKnob {41 project_colorspace l project t "set this to the project color space" T OCIOColorSpace1.in_colorspace}
  85. addUserKnob {22 python_button l "What's this all about?" -STARTLINE T "nuke.message(\"Regraining in other color spaces than the camera native linear space can lead to unexpected behaviour.\\n\\nFor example converting Alexa plates to ACEScg might introduce negative values due to ACEScg's smaller gamut. In that case converting back to ARRI Linear ALEXA Wide Gamut will probably help.\\nJust set <i>project</i> to ACEScg and <i>camera</i> to ARRI Linear ALEXA Wide Gamut.\\n\\nThis might be transferable to other cameras, but I've only tested with Alexas.\\n---------\\nBypass by setting both knobs to the same value.\")"}
  86. addUserKnob {41 camera_colorspace l camera t "set this to the camera native linear space" T OCIOColorSpace1.out_colorspace}
  87. addUserKnob {26 text_2 l " " T " "}
  88. addUserKnob {26 level l "<strong>Degrain amount"}
  89. addUserKnob {78 luminance t "Leave this at 1 if you're working on a completely degrained plate.\n\nIn case you decided to leave some luminance grain in the degrained plate (use the DegrainHelper node for this!), set this to the same value as in the DegrainHelper in order to compensate.\n\nIf the luminance degrain amount was set to 0.8, this needs to be set to 0.8 as well.\n\nYou need to select a mask of all elements that cover the plate, otherwise the grain of whole comp will be too strong " n 1}
  90. luminance 1
  91. addUserKnob {26 divider01 l " "}
  92. addUserKnob {41 degrain_amount_mask l "degrain amount mask" t "Use this channel from the mask input to specify in what area of the comp the missing luminance grain needs to be compensated." T Multiply1.maskChannelMask}
  93. addUserKnob {41 invert_mask l invert -STARTLINE T Multiply1.invert_mask}
  94. addUserKnob {26 spacer02 l " " T " "}
  95. addUserKnob {26 divider02 l <strong>Analyze}
  96. addUserKnob {3 number_of_frames l "number of frames" t "Set the number of sample frames to be spread across the input range.\n\nMore frames lead to higher accuracy.\n\nIf there are particularly bright or dark frames, set them manually in the knob below to make sure they are part of the analysis.\n\nIf you want to set all sample frames manually, set this to 0 and add the frames in the knob below."}
  97. number_of_frames 10
  98. addUserKnob {1 additional_frames l "additional frames" t "Set additional frames like this:\n\n1001,1020,1053 (single frames)\n1020-1040 (frame ranges)\n1020-1040x4 (frame ranges with step)"}
  99. addUserKnob {3 sample_count l "sample count" t "The samples are spread across the sample range (which gets calculated automatically) based on the AlexaV3LogC curve. This results in more samples in the dark areas and less samples in the brights.\n\nMore samples lead to a more detailed response curve (while the accuracy is limited by the quality of the degrain)."}
  100. sample_count 20
  101. addUserKnob {22 analyze l Analyze t "this is where the magic happens" T "import base64\nthis = nuke.thisNode()\n\n\ndef _sample_count(this):\n \"\"\"returns the sample count\"\"\"\n\n sample_count = int(this\['sample_count'].value())\n\n if sample_count <= 0:\n raise RuntimeError('Enter a sample count greater than 0')\n\n else:\n return sample_count\n\n\ndef _generate_frame_list(this):\n \"\"\"converts the frames submitted by the user into a list\"\"\"\n\n frame_list = \[]\n number_of_frames = int(this\['number_of_frames'].value())\n additional_frames = this\['additional_frames'].value()\n\n if number_of_frames < 1 and additional_frames is '':\n raise RuntimeError('Either set the number of frames > 0\\nor define additional frames')\n\n first_frame = max(this.input(1).firstFrame(), this.input(2).firstFrame())\n last_frame = min(this.input(1).lastFrame(), this.input(2).lastFrame())\n\n if number_of_frames > 0:\n distance = (last_frame - first_frame) / (number_of_frames)\n frame = first_frame + distance / 2\n\n for x in range(number_of_frames):\n int_frame = int(round(frame))\n if int_frame not in frame_list:\n frame_list.append(int_frame)\n\n frame += distance\n\n frange = nuke.FrameRanges(additional_frames.split(','))\n\n for r in frange:\n for f in r:\n if f >= first_frame and f <= last_frame:\n if f not in frame_list:\n frame_list.append(f)\n\n frame_list.sort()\n\n return frame_list\n\n\ndef _setup_for_multiframe(frame_list):\n \"\"\" arranges all sample frames next to each other, starting at frame 0\n and sets the frame number knob of the FrameBlend node\"\"\"\n\n time_warp = nuke.toNode('TimeWarp1')\n time_warp\['lookup'].clearAnimated()\n time_warp\['lookup'].setAnimated()\n anim_list = \[]\n\n for n, frame in enumerate(frame_list):\n anim_list.append(nuke.AnimationKey(n, frame))\n\n anim = time_warp\['lookup'].animation(0)\n anim.addKey(anim_list)\n\n frame_blend = nuke.toNode('FrameBlend1')\n frame_blend\['endframe'].setValue(len(frame_list)-1)\n\n\ndef _generate_sample_list(sample_count, sample_range, sample_radius):\n \"\"\"generate a list of sample values spread equally between the\n min and max values of the sample range\"\"\"\n\n sample_list = \[]\n\n for item in range(0, sample_count):\n sample_list.append(float(item) / sample_count * (sample_range\[1] - sample_range\[0]) + sample_range\[0] + sample_radius)\n\n return sample_list\n\n\ndef _get_sample_range(channel, channel_list, frame_list):\n \"\"\" samples the minimum and maximum values of the given frame range and\n sets the sample range to those values\"\"\"\n\n curve_tool = nuke.toNode('CurveTool_Range')\n min_knob = curve_tool\['minlumapixvalue']\n max_knob = curve_tool\['maxlumapixvalue']\n\n min_knob.setAnimated()\n max_knob.setAnimated()\n\n curve_tool\['channels'].setValue(channel)\n\n nuke.execute(curve_tool, nuke.FrameRanges(frame_list))\n\n index = channel_list.index(channel)\n min_list = \[key.y for key in min_knob.animation(index).keys()]\n max_list = \[key.y for key in max_knob.animation(index).keys()]\n\n min_value = min(min_list)\n max_value = max(max_list)\n\n min_knob.clearAnimated()\n max_knob.clearAnimated()\n curve_tool\['minlumapixdata'].clearAnimated()\n curve_tool\['maxlumapixdata'].clearAnimated()\n\n return \[min_value, max_value]\n\n\ndef _sample_it(keyer, curve_tool, sample, sample_radius):\n \"\"\"analyze the grain level per channel and sample value in the sample range\"\"\"\n\n keyer\['temp_expr0'].setValue(str(sample - sample_radius))\n keyer\['temp_expr1'].setValue(str(sample + sample_radius))\n\n intensity_knob = curve_tool\['intensitydata']\n intensity_knob.clearAnimated()\n intensity_knob.setAnimated()\n\n nuke.execute(curve_tool, nuke.frame(), nuke.frame())\n sample_values = intensity_knob.value()\n intensity_knob.clearAnimated()\n\n return sample_values\n\n\ndef check_inputs(this):\n if this.input(1) is None:\n raise RuntimeError('no plate connected')\n\n if this.input(2) is None:\n raise RuntimeError('no degrained plate connected')\n\n def format_tuple(node):\n return node.format().width(), node.format().height(), node.format().pixelAspect()\n\n if format_tuple(this.input(1)) != format_tuple(this.input(2)):\n raise RuntimeError(\"Format missmatch: Make sure the formats of plate and degrained plate match.\")\n\n\ndef start(this):\n \"\"\"let's do this!\"\"\"\n\n check_inputs(this)\n\n with this:\n frame_list = _generate_frame_list(this)\n _setup_for_multiframe(frame_list)\n sample_count = _sample_count(this)\n\n blank = base64.b64decode('cmVkIHtjdXJ2ZX0KZ3JlZW4ge2N1cnZlfQpibHVlIHtjdXJ2ZX0=').decode('ascii')\n\n lut = nuke.toNode('Sampler1')\['lut']\n lut.fromScript(blank)\n\n channel_list = \['red', 'green', 'blue']\n\n keyer = nuke.toNode('Expression2')\n copy = nuke.toNode('Copy2')\n\n curve_tool = nuke.toNode('CurveTool')\n pixel = curve_tool\['ROI'].value()\[2] * curve_tool\['ROI'].value()\[3]\n\n task = nuke.ProgressTask('Analysing...')\n step = 100.0 / 3 / sample_count\n progress = step\n\n time_warp = nuke.toNode('TimeWarp1')\n frame_blend = nuke.toNode('FrameBlend1')\n\n time_warp\['disable'].setValue(False)\n frame_blend\['disable'].setValue(False)\n\n for channel in channel_list:\n task.setMessage('\{\} range'.format(channel))\n\n copy\['from0'].setValue('rgba.\{\}'.format(channel))\n\n sample_range = _get_sample_range(channel, channel_list, frame_list)\n sample_radius = (sample_range\[1] - sample_range\[0]) / sample_count / 2\n sample_list = _generate_sample_list(sample_count, sample_range, sample_radius)\n\n for sample in sample_list:\n if task.isCancelled():\n return\n\n task.setProgress(int(progress))\n\n sample_values = _sample_it(keyer, curve_tool, sample, sample_radius)\n\n task.setMessage('\{\} channel at \{\}'.format(channel, round(sample, 2)))\n\n if sample_values\[3] * pixel >= 10:\n lut.setValueAt(sample_values\[0] / sample_values\[3], sample_values\[1] / sample_values\[3], channel_list.index(channel))\n\n progress += step\n\n time_warp\['lookup'].clearAnimated()\n time_warp\['disable'].setValue(True) # hopefully prevents slowing down the comp\n frame_blend\['disable'].setValue(True) # hopefully prevents slowing down the comp\n\n del task\n\n\nstart(this)\n" +STARTLINE}
  102. addUserKnob {26 divider03 l " "}
  103. addUserKnob {41 analysis_mask l "analysis mask" t "Use this channel from the mask input to control what area of the plate will be analyzed.\n\nUsefull if the degrain is obviously bad in some areas." T ChannelMerge1.A}
  104. addUserKnob {6 invert_1 l invert -STARTLINE}
  105. addUserKnob {20 Adjust_tab l Adjust}
  106. addUserKnob {22 whatsthis l "What am I looking at?" T "nuke.message(\"After the analysis you'll see the sampled grain response curves here. On the x-axis is the brightness of the image and on the y-axis the grain intensity. Grain increases with brightness, so <strong>the slope of the curves should always be positive</strong> (they should always go up &#8599;).<br><br>The quality of the curves depends entirely on the quality of the degrain. If the curves look wrong (for example they go up and down), try to improve the degrain first. If they still look wrong and the resulting regrain doesn't work well enough, you can try to improve the curves here by deleting/correcting all points that don't follow an upwards trend.<br><br>You can also extend the curves (again: with an upwards trend) if the comp has values that don't exist in the plate.<br><br>Note: The curve is used for both the normalization as well as the adaptation of the grain, so it doesn't give direct control of the grain intensity.\")" +STARTLINE}
  107. addUserKnob {41 lut l "" +STARTLINE T Sampler1.lut}
  108. addUserKnob {20 Replace_tab l Replace}
  109. addUserKnob {6 external_grain l "use external grain" t "Use external grain from a second DasGrain, with the output set to 'normalised grain', to replace masked area.\nConnect it to the 'external grain' input of this DasGrain (it's a bit hidden on the left side of the node)." +STARTLINE}
  110. addUserKnob {26 divider04 l <strong>Scatter}
  111. addUserKnob {26 divider05 l <strong>Scatter +HIDDEN T "<span style=\"color:red\">Make sure you're sampling an area without any plate detail.</a>"}
  112. addUserKnob {6 scatter l activate t "Activates the scatter function. It generates a new grain based on the plate grain in the sample box using a Voronoi noise." +STARTLINE}
  113. addUserKnob {41 useGPUIfAvailable l "Use GPU if available" -STARTLINE T VoronoiScatter.useGPUIfAvailable}
  114. addUserKnob {15 box l "sample box" t "Define an area that is used as a source for the scatter function. The plate grain in this area should be as even as possible, without any visible detail."}
  115. box {100 100 500 300}
  116. addUserKnob {3 sample_frame l "sample frame" t "The frame at which the grain is being sampled. Is set automatically once the sample box is changed." +DISABLED}
  117. sample_frame 1
  118. addUserKnob {4 stereo l "stereo behaviour" t "randomize offset per view: same voronoy pattern for all views, but different offset\n\nrandomize pattern per view: different voronoy pattern for every view" M {none "randomize offset per view" "randomize pattern per view" ""}}
  119. addUserKnob {26 spacer06 l "" +STARTLINE T " "}
  120. addUserKnob {6 overlay l "overlay cell pattern" t "Overlay the cell pattern of the voronoy noise. Useful to check where the seams are and if distortion or blending is necessary." +STARTLINE}
  121. addUserKnob {7 cell_size l "cell size" t "Cell size of the scatter. Shoudn't be too small, as lower grain frequencies might break.\nCan't be too big either, to prevent it from breaking the border of the samplebox (will error if it does)." R 5 100}
  122. cell_size 40
  123. addUserKnob {26 spacer07 l "" +STARTLINE T " "}
  124. addUserKnob {20 concealer l "edge concealer" n 1}
  125. concealer 0
  126. addUserKnob {26 concealer_help l " " T "If you can see the voronoi pattern in the grain QC output,\nincrease the edge blend size."}
  127. addUserKnob {3 edge_blend_size l "edge blend size" t "Set the output to grain QC. If you see the cell seams, increase the edge blend size to conceal them.\n\nThis is a bit hacky and slow."}
  128. addUserKnob {26 tip l "" -STARTLINE T "sloooow - keep this below 3 if possible"}
  129. addUserKnob {26 distortion_help l " " T "\nDistortion might help as well, if somehow the straight\nseams are visible (you might want to toggle the overlay\nwhile adjusting)."}
  130. addUserKnob {7 amplitude R 0 50}
  131. addUserKnob {7 frequency R 0 50}
  132. frequency 15
  133. addUserKnob {20 endGroup n -1}
  134. addUserKnob {26 divider06 l "" +STARTLINE}
  135. addUserKnob {41 replace_mask l "replace mask" t "Use this channel from the mask input to specify where you want to use scattered grain instead of the adapted plate grain." -STARTLINE T Merge9.maskChannelMask}
  136. addUserKnob {41 invert_mask_1 l invert -STARTLINE T Merge9.invert_mask}
  137. addUserKnob {20 GrainGroupEnd l "" +STARTLINE n -3}
  138. addUserKnob {20 Help_tab l Help}
  139. addUserKnob {26 basic_setup l "" +STARTLINE T "<font size=\"5\">Basic setup</font>"}
  140. addUserKnob {26 ""}
  141. addUserKnob {26 explanation l "" +STARTLINE T "<strong>Bold</strong> steps are always necessary"}
  142. addUserKnob {26 steps l "" +STARTLINE T "<br><strong>1. This should be the only regrain node in your comp.<br>2. Connect <i>plate</i>, <i>degrained plate</i> and <i>comp</i>.<br>&nbsp;&nbsp;&nbsp;&nbsp;The comp should be done on the degrained plate!</strong><br>3. Set the <i>luminance degrain amount</i>.<br><strong>4. Press the <i>Analyze</i> button.</strong><br>5. Correct the response curves in the <i>Adjust</i> tab.<br>6. Move the <i>sample box</i> to an area without any plate detail and activate <i>scatter</i>.<br>7. If necessary, activate <i>edge blend</i> and/or <i>distortion</i> to conceal seams."}
  143. addUserKnob {26 in_depth l "" +STARTLINE T "<br>For an in depth explanation of the steps, read the tooltips and check out this video:<br><a href=\"https://vimeo.com/284820390/\"><span style=\"color:#C8C8C8;\">https://vimeo.com/284820390</a>"}
  144. addUserKnob {26 pushthebutton l "" +STARTLINE T "<br><br>If the result is not as expected and you don't know why, push this button:"}
  145. addUserKnob {22 troubleshoot l Troubleshoot t HEEEEEEELP T "import base64\n\nmessages = \[]\n\nthis = nuke.thisNode()\n\n#########################\n\nif this.input(0) is None or this.input(1) is None or this.input(2) is None:\n messages.append(\"<font color='red'><strong>ERROR</strong></font> Plate, degrained plate and comp need to be connected to the appropriate inputs.\")\n\n#########################\n\nelse:\n\n def format_to_tuple(g):\n \"\"\"returns (1024, 786, 2.0)\n \"\"\"\n return (g.format().width(), g.format().height(), g.format().pixelAspect())\n\n format_set = set(\[\n format_to_tuple(this.input(0)),\n format_to_tuple(this.input(1)),\n format_to_tuple(this.input(2)),\n ])\n if len(format_set) != 1:\n messages.append(\"<font color='orange'><strong>WARNING</strong></font> Format missmatch: Make sure formats of plate, degrained plate and comp match.\")\n\n if (this.input(1).firstFrame() != this.input(2).firstFrame()) or (this.input(1).lastFrame() != this.input(2).lastFrame()):\n messages.append(\"<font color='orange'><strong>WARNING</strong></font> The frame ranges of plate and degrained plate don't match. Double check that they belong together.\")\n\n#########################\n\nmessages.append(\"Double check that plate and degrained plate haven't been modified in any way (paint, despill, etc).\")\n\n#########################\n\nif this\['luminance'].getValue() == 1:\n messages.append(\"Are you working on a completely degrained plate? If not, you might have to set the luminance degrain amount.\")\n\n#########################\n\nblank = base64.b64decode('cmVkIHtjdXJ2ZX0KZ3JlZW4ge2N1cnZlfQpibHVlIHtjdXJ2ZX0=').decode('ascii')\n\nwith this:\n Sampler = nuke.toNode('Sampler1') \n if Sampler\['lut'].toScript() == blank:\n messages.append(\"<font color='red'><strong>ERROR</strong></font> You haven't pressed the Analyze button yet!\")\n\n#########################\n\nclass BadThings(Exception): pass\n\ndef thingy():\n with this:\n Sampler = nuke.toNode('Sampler1')\n list = this\['lut'].toScript().replace('\}','').split('\\n')\n for item in list:\n sample_value = 0\n for value in item.split(' '):\n try:\n value == float(value)\n if value < sample_value:\n raise BadThings(\"<font color='orange'><strong>WARNING</strong></font> Check and fix the response curves. Their slopes should always be positive (the curves should always go up &#8599;).\")\n \n else:\n sample_value = value\n except ValueError:\n # Ignore non-numeric things like x-values of \"x5.46\" and channel names like \"red\{\" etc\n pass\ntry:\n thingy()\nexcept BadThings as e:\n messages.append(str(e))\n \n#########################\n\nif this\['scatter'].value() == True:\n if this\['box'].getValue() == \[100.0, 100.0, 500.0, 300.0]:\n messages.append(\"<font color='orange'><strong>WARNING</strong></font> Scatter has been activated, but the sample box is still in its default position. Are you sure that's a good area to sample?\")\n\n#########################\n\nmessages.append(\"Did you copy/paste DasGrain from another script? Make sure to reanalyze and to reset the sample area if you are using scatter.\")\n\n#########################\n\nif len(messages) > 0:\n nuke.message(\"<font size=\\\"5\\\">Things worth checking</font><br><br>\"\n \"%s<br><br><br>If any of this doesn't make sense to you, it might be worth checking out the video on vimeo.\" % (\n \"<hr>\".join(\"%s: %s\" % (i+1, m) for i, m in enumerate(messages))))\n" +STARTLINE}
  146. addUserKnob {26 dont_despair l "" +STARTLINE T "<br>If it still doesn't work and you're about to flip the table, send me a <a href=\"mailto:holtzf+nuke@gmail.com?subject=Help with DasGrain v1.7.8\"><span style=\"color:#C8C8C8;\">mail</a>.<br>I'm happy to help! :)"}
  147. addUserKnob {20 Info_tab l Info}
  148. addUserKnob {26 dasname l "" +STARTLINE T "<font size='5'>DasGrain</font> v1.8<br>"}
  149. addUserKnob {26 text_1 l "" +STARTLINE T "DasGrain makes regraining as simple as clicking a few buttons.<br>Follow the steps in the <i>Help</i> tab and you'll have a perfect\nregrain<br>in no time!"}
  150. addUserKnob {26 ""}
  151. addUserKnob {26 info l "" +STARTLINE T "Last change: 2021-03-07\n\n"}
  152. addUserKnob {26 name_1 l "" +STARTLINE T "Fabian Holtz"}
  153. addUserKnob {26 mail l "" +STARTLINE T "<a href=\"mailto:holtzf+nuke@gmail.com?subject=Help with DasGrain v1.7.8\"><span style=\"color:#C8C8C8;\">holtzf+nuke@gmail.com</a>"}
  154. addUserKnob {26 testimonial l "" +STARTLINE T "<br><br><br><i>&laquo;Totally awesome!&raquo;</i><br>&mdash; anonymous<br><br>"}
  155. addUserKnob {26 ""}
  156. addUserKnob {26 credit l "" +STARTLINE T "<br>VoronoiScatter based on <a href=\"http://www.nukepedia.com/blink/image/voronoi/\"><span style=\"color:#C8C8C8;\">Ivan Busquets' implementation</a> of<br> libNoise's\nVoronoi generator"}
  157. addUserKnob {26 thanks l "" +STARTLINE T "<br>Special thanks to Ben Dickson for bearing with my questions and<br>problems and RSP comp for the valuable feedback."}
  158. }
  159. BackdropNode {
  160. inputs 0
  161. name BackdropNode1
  162. tile_color 0x7f7f7fff
  163. label "normalise grain"
  164. note_font_size 30
  165. xpos 170
  166. ypos 1662
  167. bdwidth 320
  168. bdheight 110
  169. }
  170. BackdropNode {
  171. inputs 0
  172. name BackdropNode11
  173. tile_color 0x7f7f7fff
  174. label "add grain"
  175. note_font_size 30
  176. xpos 830
  177. ypos 2766
  178. bdwidth 320
  179. bdheight 110
  180. }
  181. BackdropNode {
  182. inputs 0
  183. name BackdropNode13
  184. tile_color 0x7f7f7fff
  185. label scatter
  186. note_font_size 30
  187. xpos -50
  188. ypos 2022
  189. bdwidth 320
  190. bdheight 110
  191. }
  192. BackdropNode {
  193. inputs 0
  194. name BackdropNode14
  195. tile_color 0x7f7f7fff
  196. label "analyze grain"
  197. note_font_size 30
  198. xpos -159
  199. ypos 606
  200. bdwidth 319
  201. bdheight 877
  202. }
  203. BackdropNode {
  204. inputs 0
  205. name BackdropNode2
  206. tile_color 0x7f7f7fff
  207. label "grain response curve"
  208. note_font_size 30
  209. xpos 610
  210. ypos 2574
  211. bdwidth 320
  212. bdheight 110
  213. }
  214. BackdropNode {
  215. inputs 0
  216. name BackdropNode3
  217. tile_color 0x7f7f7fff
  218. label QC
  219. note_font_size 30
  220. xpos 1050
  221. ypos 3222
  222. bdwidth 320
  223. bdheight 110
  224. }
  225. BackdropNode {
  226. inputs 0
  227. name BackdropNode4
  228. tile_color 0x7f7f7fff
  229. label "grain response curve"
  230. note_font_size 30
  231. xpos 610
  232. ypos 1422
  233. bdwidth 320
  234. bdheight 110
  235. }
  236. BackdropNode {
  237. inputs 0
  238. name BackdropNode5
  239. tile_color 0x7f7f7fff
  240. label "adapt grain"
  241. note_font_size 30
  242. xpos 170
  243. ypos 2574
  244. bdwidth 320
  245. bdheight 110
  246. }
  247. BackdropNode {
  248. inputs 0
  249. name BackdropNode6
  250. tile_color 0x7f7f7fff
  251. label "sample range"
  252. note_font_size 30
  253. xpos -490
  254. ypos 606
  255. bdwidth 320
  256. bdheight 110
  257. }
  258. BackdropNode {
  259. inputs 0
  260. name BackdropNode7
  261. tile_color 0x7f7f7fff
  262. label "luminance level"
  263. note_font_size 30
  264. xpos 280
  265. ypos -282
  266. bdwidth 760
  267. bdheight 685
  268. }
  269. BackdropNode {
  270. inputs 0
  271. name BackdropNode8
  272. tile_color 0x7f7f7fff
  273. label "plate grain"
  274. note_font_size 30
  275. xpos 170
  276. ypos 606
  277. bdwidth 320
  278. bdheight 110
  279. }
  280. BackdropNode {
  281. inputs 0
  282. name BackdropNode9
  283. tile_color 0x7f7f7fff
  284. label replace
  285. note_font_size 30
  286. xpos 60
  287. ypos 2191
  288. bdwidth 540
  289. bdheight 226
  290. }
  291. Input {
  292. inputs 0
  293. name DEGRAINED_PLATE
  294. label "\[value number]"
  295. note_font_size 30
  296. xpos 730
  297. ypos -896
  298. number 2
  299. }
  300. OCIOColorSpace {
  301. in_colorspace {{OCIOColorSpace1.in_colorspace}}
  302. out_colorspace {{OCIOColorSpace1.out_colorspace}}
  303. name OCIOColorSpace2
  304. xpos 730
  305. ypos -490
  306. }
  307. Dot {
  308. name Dot9
  309. xpos 764
  310. ypos -390
  311. }
  312. set N8ca3c00 [stack 0]
  313. Dot {
  314. name Dot28
  315. xpos 764
  316. ypos -198
  317. }
  318. set N8ca3800 [stack 0]
  319. Dot {
  320. name Dot32
  321. xpos 764
  322. ypos 234
  323. }
  324. set N8ca3400 [stack 0]
  325. push $N8ca3800
  326. Dot {
  327. name Dot27
  328. xpos 624
  329. ypos -198
  330. }
  331. Colorspace {
  332. colorspace_out YCbCr
  333. name Colorspace1
  334. xpos 590
  335. ypos -130
  336. }
  337. Dot {
  338. name Dot7
  339. xpos 624
  340. ypos -54
  341. }
  342. set N8ca2800 [stack 0]
  343. Input {
  344. inputs 0
  345. name PLATE
  346. label "\[value number]"
  347. note_font_size 30
  348. xpos 290
  349. ypos -892
  350. number 1
  351. }
  352. Dot {
  353. name Dot50
  354. xpos 324
  355. ypos -726
  356. }
  357. set N8ca2000 [stack 0]
  358. OCIOColorSpace {
  359. in_colorspace scene_linear
  360. out_colorspace scene_linear
  361. name OCIOColorSpace1
  362. xpos 290
  363. ypos -490
  364. }
  365. Dot {
  366. name Dot29
  367. xpos 324
  368. ypos -198
  369. }
  370. set N8ca1400 [stack 0]
  371. Dot {
  372. name Dot6
  373. xpos 464
  374. ypos -198
  375. }
  376. Colorspace {
  377. colorspace_out YCbCr
  378. name Colorspace2
  379. xpos 430
  380. ypos -130
  381. }
  382. Merge2 {
  383. inputs 2
  384. operation from
  385. bbox B
  386. Achannels rgb
  387. Bchannels rgb
  388. output rgb
  389. name Merge4
  390. xpos 430
  391. ypos -58
  392. }
  393. Multiply {
  394. channels rgb
  395. value {{"1 / parent.luminance - 1"} 0 0 0}
  396. name Multiply6
  397. xpos 430
  398. ypos 14
  399. }
  400. Dot {
  401. name Dot31
  402. xpos 464
  403. ypos 90
  404. }
  405. push $N8ca2800
  406. Merge2 {
  407. inputs 2
  408. operation plus
  409. bbox B
  410. Achannels rgb
  411. Bchannels rgb
  412. output rgb
  413. name Merge5
  414. xpos 590
  415. ypos 86
  416. }
  417. Colorspace {
  418. colorspace_in YCbCr
  419. name Colorspace3
  420. xpos 590
  421. ypos 158
  422. }
  423. Merge2 {
  424. inputs 2
  425. operation from
  426. bbox B
  427. Achannels rgb
  428. Bchannels rgb
  429. output rgb
  430. name Merge6
  431. xpos 590
  432. ypos 230
  433. }
  434. Dot {
  435. name Dot35
  436. xpos 624
  437. ypos 306
  438. }
  439. set N7f8bec00 [stack 0]
  440. push $N8ca3400
  441. Merge2 {
  442. inputs 2
  443. operation from
  444. bbox B
  445. Achannels rgb
  446. Bchannels rgb
  447. output rgb
  448. name Merge7
  449. xpos 730
  450. ypos 302
  451. disable {{"Multiply6.value.r == 0"}}
  452. }
  453. Dot {
  454. name Dot2
  455. xpos 764
  456. ypos 522
  457. }
  458. set N7f8be400 [stack 0]
  459. Dot {
  460. name Dot30
  461. xpos 764
  462. ypos 690
  463. }
  464. set N7f8be000 [stack 0]
  465. Dot {
  466. name Dot55
  467. xpos 764
  468. ypos 1170
  469. }
  470. set N7f8bdc00 [stack 0]
  471. Input {
  472. inputs 0
  473. name mask
  474. label "\[value number]"
  475. note_font_size 30
  476. xpos 1170
  477. ypos -896
  478. number 3
  479. }
  480. Dot {
  481. name Dot39
  482. xpos 1204
  483. ypos 258
  484. }
  485. set N7f8bd400 [stack 0]
  486. Dot {
  487. name Dot26
  488. xpos 1204
  489. ypos 1074
  490. }
  491. set N7f8bd000 [stack 0]
  492. Invert {
  493. name Invert2
  494. xpos 180
  495. ypos 1064
  496. disable {{!parent.invert_1}}
  497. }
  498. push $N7f8be000
  499. push $N8ca1400
  500. Merge2 {
  501. inputs 2
  502. operation from
  503. bbox B
  504. Achannels rgb
  505. Bchannels rgb
  506. output rgb
  507. name Merge27
  508. xpos 290
  509. ypos 686
  510. }
  511. Dot {
  512. name Dot3
  513. xpos 324
  514. ypos 786
  515. }
  516. set N7f8bc400 [stack 0]
  517. Dot {
  518. name Dot5
  519. xpos 104
  520. ypos 786
  521. }
  522. set N7fadfc00 [stack 0]
  523. push $N7fadfc00
  524. Copy {
  525. inputs 2
  526. from0 {{{parent.Copy2.from0}}}
  527. to0 rgba.red
  528. name Copy3
  529. xpos 70
  530. ypos 848
  531. }
  532. Expression {
  533. expr0 abs(r)
  534. channel1 {none none none rgba.alpha}
  535. expr1 "r == 0"
  536. channel2 none
  537. channel3 none
  538. name Expression4
  539. xpos 70
  540. ypos 926
  541. }
  542. set N7fadf400 [stack 0]
  543. push $N7f8be400
  544. Colorspace {
  545. colorspace_out AlexaV3LogC
  546. name Colorspace5
  547. xpos 70
  548. ypos 518
  549. }
  550. Clamp {
  551. maximum_enable false
  552. name Clamp2
  553. xpos -40
  554. ypos 512
  555. }
  556. Dot {
  557. name Dot1
  558. xpos -116
  559. ypos 522
  560. }
  561. set N7fade800 [stack 0]
  562. Dot {
  563. name Dot48
  564. xpos -116
  565. ypos 786
  566. }
  567. set N7fade400 [stack 0]
  568. push $N7fade400
  569. Copy {
  570. inputs 2
  571. from0 rgba.blue
  572. to0 rgba.red
  573. name Copy2
  574. xpos -150
  575. ypos 848
  576. }
  577. Expression {
  578. temp_name0 min
  579. temp_name1 max
  580. channel0 {none none none rgba.alpha}
  581. expr0 "r >= min && r <= max"
  582. channel1 none
  583. channel2 none
  584. channel3 none
  585. name Expression2
  586. xpos -150
  587. ypos 926
  588. }
  589. Dot {
  590. name Dot4
  591. xpos -116
  592. ypos 1002
  593. }
  594. ChannelMerge {
  595. inputs 2
  596. operation stencil
  597. name ChannelMerge2
  598. xpos -40
  599. ypos 985
  600. }
  601. push $N7fadf400
  602. Copy {
  603. inputs 2
  604. from0 rgba.alpha
  605. to0 rgba.alpha
  606. name Copy1
  607. xpos 70
  608. ypos 992
  609. }
  610. ChannelMerge {
  611. inputs 2
  612. A -rgba.green
  613. operation multiply
  614. name ChannelMerge1
  615. xpos 70
  616. ypos 1057
  617. disable {{!A}}
  618. }
  619. Copy {
  620. inputs 2
  621. from0 {{{parent.Copy2.from0}}}
  622. to0 rgba.green
  623. name Copy4
  624. xpos 70
  625. ypos 1160
  626. }
  627. Premult {
  628. channels {rgba.red rgba.green -rgba.blue none}
  629. name Premult1
  630. xpos 70
  631. ypos 1238
  632. }
  633. TimeWarp {
  634. lookup 1081
  635. time ""
  636. filter nearest
  637. name TimeWarp1
  638. xpos 70
  639. ypos 1286
  640. disable true
  641. }
  642. FrameBlend {
  643. channels {rgba.red rgba.green -rgba.blue rgba.alpha}
  644. startframe 0
  645. endframe 9
  646. userange true
  647. name FrameBlend1
  648. xpos 70
  649. ypos 1352
  650. disable true
  651. }
  652. CurveTool {
  653. avgframes 0
  654. channels {rgba.red rgba.green -rgba.blue rgba.alpha}
  655. ROI {0 0 {width} {height}}
  656. name CurveTool
  657. xpos 70
  658. ypos 1424
  659. }
  660. push $N7fade800
  661. Dot {
  662. name Dot16
  663. xpos -336
  664. ypos 522
  665. }
  666. CurveTool {
  667. operation "Max Luma Pixel"
  668. channels {-rgba.red -rgba.green rgba.blue none}
  669. ROI {0 0 {width} {height}}
  670. name CurveTool_Range
  671. xpos -370
  672. ypos 680
  673. }
  674. Sampler {
  675. inputs 0
  676. lut {red {curve}
  677. green {curve}
  678. blue {curve}}
  679. name Sampler1
  680. onCreate "n = nuke.thisNode()\nn\['sampler'].setEnabled(False)"
  681. knobChanged "n = nuke.thisNode()\nk = nuke.thisKnob()\np = nuke.thisParent()\n\nif k.name() == 'lut':\n with p:\n for c in \['ColorLookup1','ColorLookup2']:\n nuke.toNode(c)\['lut'].fromScript(k.toScript())"
  682. xpos 840
  683. ypos 1502
  684. }
  685. push $N8ca2000
  686. Dot {
  687. name Dot51
  688. xpos 115
  689. ypos -726
  690. }
  691. Input {
  692. inputs 0
  693. name COMP
  694. label "\[value number]"
  695. note_font_size 30
  696. xpos 950
  697. ypos -896
  698. }
  699. Dot {
  700. name Dot49
  701. xpos 984
  702. ypos -605
  703. }
  704. set N7fef9c00 [stack 0]
  705. Switch {
  706. inputs 2
  707. which {{parent.meta}}
  708. name Switch1
  709. xpos 81
  710. ypos -609
  711. }
  712. Dot {
  713. name Dot54
  714. xpos 115
  715. ypos -486
  716. }
  717. Dot {
  718. name Dot52
  719. xpos -685
  720. ypos -486
  721. }
  722. Dot {
  723. name Dot53
  724. xpos -685
  725. ypos 3762
  726. }
  727. push $N7f8bd400
  728. Dot {
  729. name Dot40
  730. xpos 874
  731. ypos 258
  732. }
  733. push $N7f8bec00
  734. Dot {
  735. name Dot34
  736. xpos 624
  737. ypos 378
  738. }
  739. Multiply {
  740. inputs 1+1
  741. channels rgb
  742. value 0
  743. maskChannelMask -rgba.red
  744. name Multiply1
  745. xpos 840
  746. ypos 374
  747. }
  748. push $N7fef9c00
  749. OCIOColorSpace {
  750. in_colorspace {{OCIOColorSpace1.in_colorspace}}
  751. out_colorspace {{OCIOColorSpace1.out_colorspace}}
  752. name OCIOColorSpace3
  753. xpos 950
  754. ypos -490
  755. }
  756. Dot {
  757. name Dot44
  758. xpos 984
  759. ypos -390
  760. }
  761. set N7ff3f000 [stack 0]
  762. Merge2 {
  763. inputs 2
  764. operation from
  765. bbox B
  766. Achannels rgb
  767. Bchannels rgb
  768. output rgb
  769. name Merge8
  770. xpos 950
  771. ypos 374
  772. disable {{"Multiply6.value.r == 0"}}
  773. }
  774. Dot {
  775. name Dot18
  776. xpos 984
  777. ypos 2658
  778. }
  779. set N7ff3e800 [stack 0]
  780. ColorLookup {
  781. lut {master {}
  782. red {curve}
  783. green {curve}
  784. blue {curve}
  785. alpha {}}
  786. name ColorLookup2
  787. xpos 730
  788. ypos 2654
  789. }
  790. push $N7f8bd000
  791. Dot {
  792. name Dot38
  793. xpos 1204
  794. ypos 1842
  795. }
  796. Dot {
  797. name Dot37
  798. xpos 544
  799. ypos 1842
  800. }
  801. Dot {
  802. name Dot22
  803. xpos 544
  804. ypos 2271
  805. }
  806. set N7ff3d800 [stack 0]
  807. Dot {
  808. name Dot20
  809. xpos 544
  810. ypos 2391
  811. }
  812. push $N7ff3d800
  813. Dot {
  814. name Dot17
  815. xpos 434
  816. ypos 2271
  817. }
  818. set N7ff3d000 [stack 0]
  819. Dot {
  820. name Dot13
  821. xpos 214
  822. ypos 2271
  823. }
  824. Input {
  825. inputs 0
  826. name external_grain
  827. label "\[value number]"
  828. note_font_size 30
  829. xpos -150
  830. ypos 1716
  831. number 4
  832. }
  833. Dot {
  834. name Dot21
  835. xpos -116
  836. ypos 1938
  837. }
  838. push $N7f8bdc00
  839. ColorLookup {
  840. channels rgb
  841. lut {master {}
  842. red {curve}
  843. green {curve}
  844. blue {curve}
  845. alpha {}}
  846. name ColorLookup1
  847. xpos 730
  848. ypos 1502
  849. }
  850. Dot {
  851. name Dot24
  852. xpos 764
  853. ypos 1746
  854. }
  855. push $N7f8bc400
  856. Dot {
  857. name Dot33
  858. xpos 324
  859. ypos 1386
  860. }
  861. MergeExpression {
  862. inputs 2
  863. temp_name0 target
  864. temp_expr0 .01
  865. expr0 "Br * (target / Ar)"
  866. expr1 "Bg * (target / Ag)"
  867. expr2 "Bb * (target / Ab)"
  868. channel3 none
  869. name MergeExpression1
  870. xpos 290
  871. ypos 1742
  872. }
  873. Dot {
  874. name Dot15
  875. xpos 324
  876. ypos 1842
  877. }
  878. set N7f28ec00 [stack 0]
  879. Dot {
  880. name Dot25
  881. xpos 104
  882. ypos 1842
  883. }
  884. Switch {
  885. inputs 2
  886. which {{parent.external_grain}}
  887. name Switch2
  888. xpos 70
  889. ypos 1934
  890. }
  891. Group {
  892. name VoronoiScatter
  893. xpos 70
  894. ypos 2102
  895. disable {{!parent.scatter}}
  896. addUserKnob {20 User}
  897. addUserKnob {41 useGPUIfAvailable l "Use GPU if available" T VoroNoise.useGPUIfAvailable}
  898. addUserKnob {41 vectorize l "Vectorize on CPU" -STARTLINE T VoroNoise.vectorize}
  899. addUserKnob {15 box}
  900. box {{parent.box x1004 0 x1036 -75} {parent.box x1004 100 x1036 120} {parent.box x1004 496 x1036 325} {parent.box x1004 916 x1036 320}}
  901. addUserKnob {3 sample_frame l "sample frame"}
  902. sample_frame {{parent.sample_frame}}
  903. addUserKnob {7 cell_size l "cell size" R 0 100}
  904. cell_size {{parent.cell_size}}
  905. addUserKnob {6 overlay_pattern l "overlay pattern" -STARTLINE}
  906. overlay_pattern {{parent.overlay}}
  907. addUserKnob {3 edge_blend_size l "edge blend size"}
  908. edge_blend_size {{parent.edge_blend_size}}
  909. addUserKnob {7 amplitude R 0 100}
  910. amplitude {{parent.amplitude}}
  911. addUserKnob {7 frequency R 0 100}
  912. frequency {{parent.frequency}}
  913. addUserKnob {41 VoroNoise_Seed l Seed T VoroNoise.VoroNoise_Seed}
  914. }
  915. Input {
  916. inputs 0
  917. name Input1
  918. xpos 180
  919. ypos -879
  920. }
  921. Dot {
  922. name Dot14
  923. xpos 214
  924. ypos -750
  925. }
  926. set N7f28dc00 [stack 0]
  927. Dot {
  928. name Dot16
  929. xpos 434
  930. ypos -750
  931. }
  932. Remove {
  933. name Remove1
  934. xpos 400
  935. ypos -687
  936. }
  937. Dot {
  938. name Dot6
  939. xpos 434
  940. ypos -606
  941. }
  942. set N7f28d000 [stack 0]
  943. Dot {
  944. name Dot15
  945. xpos 654
  946. ypos -606
  947. }
  948. set N7f28cc00 [stack 0]
  949. Dot {
  950. name Dot7
  951. xpos 874
  952. ypos -606
  953. }
  954. Noise {
  955. output {rgba.red -rgba.green -rgba.blue none}
  956. replace true
  957. size {{parent.frequency} {"parent.frequency * pixel_aspect"}}
  958. zoffset {{"x + 1000"}}
  959. gamma 1
  960. name Noise1
  961. xpos 840
  962. ypos -514
  963. }
  964. Noise {
  965. output {-rgba.red rgba.green -rgba.blue none}
  966. replace true
  967. size {{parent.Noise1.size} {parent.Noise1.size}}
  968. zoffset {{x}}
  969. gamma 1
  970. name Noise2
  971. xpos 840
  972. ypos -466
  973. }
  974. Clamp {
  975. name Clamp1
  976. xpos 840
  977. ypos -424
  978. }
  979. Dot {
  980. name Dot11
  981. xpos 874
  982. ypos -366
  983. }
  984. push $N7f28cc00
  985. BlinkScript {
  986. ProgramGroup 1
  987. KernelDescription "2 \"VoroNoise\" iterate pixelWise c117be128a07c11b6d82fd34148d66b3bcac41976ec9c2082affe38e890c2c0f 2 \"src\" Read Point \"dst\" Write Point 6 \"Frequency\" Float 1 AABIQg== \"Seed\" Int 1 AAAAAA== \"aspect ratio\" Float 1 AACAPw== \"width\" Int 1 AAAAAA== \"height\" Int 1 AAAAAA== \"Randomness\" Float 1 AAAAPw== 6 \"frequency\" 1 1 \"seed\" 1 1 \"aspect_ratio\" 1 1 \"width\" 1 1 \"height\" 1 1 \"randomness\" 1 1 0"
  988. kernelSource "// Voronoi.blink\n// A test implementation of libNoise's Voronoi generator using Blink\n// Ivan Busquets - August 2013\n// Modified for DasGrain by Fabian Holtz - April 2019\n\n#define X_NOISE_GEN 1619\n#define Y_NOISE_GEN 31337\n#define Z_NOISE_GEN 6971\n#define SEED_NOISE_GEN 1013\n#define SQRT_3 1.73205081\n\ninline int IntValueNoise3D (int x, int y, int z, int seed)\n\{\n // All constants are primes and must remain prime in order for this noise\n // function to work correctly.\n int n = (\n X_NOISE_GEN * x\n + Y_NOISE_GEN * y\n + Z_NOISE_GEN * z\n + SEED_NOISE_GEN * seed)\n & 0x7fffffff;\n n = (n >> 13) ^ n;\n return (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;\n\}\n\ninline float ValueNoise3D (int x, int y, int z, int seed)\n\{\n return 1.0 - ((float)IntValueNoise3D (x, y, z, seed) / 1073741824.0);\n\}\n\nkernel VoroNoise : ImageComputationKernel<ePixelWise>\n\{\n Image<eRead> src;\n Image<eWrite, eAccessPoint> dst;\n\nparam:\n float frequency;\n int seed;\n float aspect_ratio;\n int width;\n int height;\n float randomness;\n\n\n void define() \{\n defineParam(frequency, \"Frequency\", 50.0f);\n defineParam(aspect_ratio, \"aspect ratio\", 1.0f);\n defineParam(seed, \"Seed\", 0);\n defineParam(randomness, \"Randomness\", 0.5f);\n \}\n\n\n\n\n void process(int2 pos) \{\n float x = pos.x * aspect_ratio * frequency / width;\n float y = pos.y * frequency / width;\n int xInt = (x > 0.0) ? x : x - 1;\n int yInt = (y > 0.0) ? y : y - 1;\n\n\n float minDist = 2147483647.0;\n float xCandidate = 0;\n float yCandidate = 0;\n\n float dist;\n\nfor (int yCur = yInt - 2; yCur <= yInt + 2; yCur++) \{\n for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) \{\n\n // Calculate the position and distance to the seed point inside of\n // this unit cube. Limited by the randomness value\n float xPos = xCur + (ValueNoise3D (xCur, yCur, 0, seed ) + 1 ) * randomness + (1-randomness) - 1;\n float yPos = yCur + (ValueNoise3D (xCur, yCur, 0, seed + 1) + 1 ) * randomness + (1-randomness) - 1;\n\n float xDist = xPos - x;\n float yDist = yPos - y;\n\n dist = pow(xDist, 2) + pow(yDist, 2);\n if (dist < minDist) \{\n // This seed point is closer to any others found so far, so record\n // this seed point.\n minDist = dist;\n xCandidate = xPos;\n yCandidate = yPos;\n\t\}\n \}\n\}\n\n SampleType(dst) sample(0.0f);\n\n sample.x = xCandidate / aspect_ratio / frequency;\n sample.y = yCandidate / height * width / frequency;\n sample.z = 0;\n\n dst() = sample;\n\}\n\};"
  989. rebuild ""
  990. VoroNoise_Frequency {{"width / parent.cell_size"}}
  991. VoroNoise_Seed {{"(x + (parent.parent.stereo == 2 ? \[lsearch \[value root.views] \[view]] / 2 : 0)) * 5"}}
  992. "VoroNoise_aspect ratio" {{pixel_aspect}}
  993. VoroNoise_width {{width}}
  994. VoroNoise_height {{height}}
  995. rebuild_finalise ""
  996. name VoroNoise
  997. xpos 620
  998. ypos -520
  999. }
  1000. Copy {
  1001. inputs 2
  1002. from0 rgba.red
  1003. to0 forward.u
  1004. from1 rgba.green
  1005. to1 forward.v
  1006. name Copy1
  1007. xpos 620
  1008. ypos -382
  1009. disable {{"parent.amplitude == 0"}}
  1010. }
  1011. IDistort {
  1012. uv forward
  1013. uv_offset 0.5
  1014. uv_scale {{parent.amplitude} {"uv_scale.w * pixel_aspect"}}
  1015. filter impulse
  1016. name IDistort1
  1017. xpos 620
  1018. ypos -280
  1019. disable {{"parent.amplitude == 0"}}
  1020. }
  1021. Dot {
  1022. name Dot5
  1023. xpos 654
  1024. ypos -246
  1025. }
  1026. NoTimeBlur {
  1027. rounding floor
  1028. name NoTimeBlur3
  1029. xpos 620
  1030. ypos -154
  1031. }
  1032. Transform {
  1033. translate {{"floor((x * size) % 1 * (size)) - int(size / 2)"} {"floor(x % 1 * (size)) - int(size/2)"}}
  1034. filter impulse
  1035. black_outside false
  1036. name Transform1
  1037. xpos 620
  1038. ypos -58
  1039. disable {{"parent.edge_blend_size < 1"}}
  1040. addUserKnob {20 User}
  1041. addUserKnob {3 size}
  1042. size {{"parent.edge_blend_size + 1"}}
  1043. }
  1044. Dot {
  1045. name Dot9
  1046. xpos 654
  1047. ypos 42
  1048. }
  1049. set N7f591800 [stack 0]
  1050. push $N7f28d000
  1051. Expression {
  1052. expr0 "(x + .5) / width"
  1053. expr1 "(y + .5) / height"
  1054. expr2 0
  1055. name STMapGenerator
  1056. xpos 400
  1057. ypos -514
  1058. }
  1059. NoTimeBlur {
  1060. rounding floor
  1061. name NoTimeBlur2
  1062. xpos 400
  1063. ypos -154
  1064. }
  1065. Merge2 {
  1066. inputs 2
  1067. operation from
  1068. Achannels {rgba.red rgba.green -rgba.blue none}
  1069. Bchannels {rgba.red rgba.green -rgba.blue none}
  1070. output {rgba.red rgba.green -rgba.blue none}
  1071. name Merge2
  1072. xpos 400
  1073. ypos 38
  1074. }
  1075. Dot {
  1076. name Dot10
  1077. xpos 434
  1078. ypos 210
  1079. }
  1080. push $N7f591800
  1081. Expression {
  1082. temp_name0 view_index
  1083. temp_expr0 "parent.parent.stereo == 1 ? \[lsearch \[value root.views] \[view]] / 2 : 0"
  1084. expr0 "random((r + view_index) * 1000000, 0) * (maxx - minx) + minx"
  1085. expr1 "random((g + view_index) * 1000000, 0) * (maxy - miny) + miny"
  1086. channel2 none
  1087. channel3 none
  1088. name Expression3
  1089. xpos 620
  1090. ypos 110
  1091. addUserKnob {20 User}
  1092. addUserKnob {7 frequency R 0 100}
  1093. frequency {{parent.parent.cell_size}}
  1094. addUserKnob {7 multiplier R 0 3}
  1095. multiplier 0.5
  1096. addUserKnob {15 shrink}
  1097. shrink {{"frequency * multiplier + ceil(parent.edge_blend_size / 2) + IDistort1.uv_scale.w / 2"} {"frequency * multiplier + ceil(parent.edge_blend_size / 2) + IDistort1.uv_scale.h / 2"} {"frequency * multiplier + floor(parent.edge_blend_size / 2) + IDistort1.uv_scale.w / 2"} {"frequency * multiplier + floor(parent.edge_blend_size / 2) + IDistort1.uv_scale.h / 2"}}
  1098. addUserKnob {26 ""}
  1099. addUserKnob {7 minx}
  1100. minx {{"(parent.box.x + shrink.x + .5) / width"}}
  1101. addUserKnob {7 maxx}
  1102. maxx {{"(parent.box.r - shrink.r - .5) / width"}}
  1103. addUserKnob {7 miny}
  1104. miny {{"(parent.box.y + shrink.y + .5) / height"}}
  1105. addUserKnob {7 maxy}
  1106. maxy {{"(parent.box.t - shrink.t - .5) / height"}}
  1107. }
  1108. Merge2 {
  1109. inputs 2
  1110. operation plus
  1111. Achannels {rgba.red rgba.green -rgba.blue none}
  1112. Bchannels {rgba.red rgba.green -rgba.blue none}
  1113. output {rgba.red rgba.green -rgba.blue none}
  1114. name Merge3
  1115. xpos 620
  1116. ypos 206
  1117. }
  1118. Expression {
  1119. expr0 "(r + (maxx - minx) - minx) % (maxx - minx) + minx"
  1120. expr1 "(g + (maxy - miny) - miny) % (maxy - miny) + miny"
  1121. channel2 none
  1122. channel3 none
  1123. name Expression7
  1124. xpos 620
  1125. ypos 278
  1126. addUserKnob {20 User}
  1127. addUserKnob {7 minx}
  1128. minx {{"(parent.box.x + rint(x % 1 * parent.edge_blend_size) + .5) / width"}}
  1129. addUserKnob {7 maxx}
  1130. maxx {{"(parent.box.r + rint(x % 1 * parent.edge_blend_size) - .5) / width"}}
  1131. addUserKnob {7 miny}
  1132. miny {{"(parent.box.y + rint(x % 1 * parent.edge_blend_size) + .5) / height"}}
  1133. addUserKnob {7 maxy}
  1134. maxy {{"(parent.box.t + rint(x % 1 * parent.edge_blend_size) - .5) / height"}}
  1135. }
  1136. Dot {
  1137. name Dot3
  1138. xpos 654
  1139. ypos 354
  1140. }
  1141. set N7f77f400 [stack 0]
  1142. Dot {
  1143. name Dot13
  1144. xpos 654
  1145. ypos 546
  1146. }
  1147. push $N7f77f400
  1148. Dot {
  1149. name Dot8
  1150. xpos 874
  1151. ypos 354
  1152. }
  1153. Blur {
  1154. channels rgb
  1155. size {{pixel_aspect} 1}
  1156. name Blur1
  1157. label "\[value size]"
  1158. xpos 840
  1159. ypos 440
  1160. }
  1161. Difference {
  1162. inputs 2
  1163. name Difference2
  1164. xpos 840
  1165. ypos 536
  1166. }
  1167. Expression {
  1168. channel0 {none none none rgba.alpha}
  1169. expr0 "a > 1e-9"
  1170. channel1 none
  1171. channel2 none
  1172. channel3 none
  1173. name Expression2
  1174. xpos 840
  1175. ypos 614
  1176. }
  1177. Shuffle {
  1178. red alpha
  1179. green alpha
  1180. blue alpha
  1181. name Shuffle1
  1182. label "\[value in]:\[value out]"
  1183. xpos 840
  1184. ypos 680
  1185. }
  1186. Dot {
  1187. name Dot4
  1188. xpos 874
  1189. ypos 762
  1190. }
  1191. push $N7f77f400
  1192. push $N7f28dc00
  1193. FrameHold {
  1194. first_frame {{parent.sample_frame}}
  1195. name FrameHold1
  1196. xpos 180
  1197. ypos -256
  1198. }
  1199. NoTimeBlur {
  1200. rounding floor
  1201. name NoTimeBlur1
  1202. xpos 180
  1203. ypos -154
  1204. }
  1205. STMap {
  1206. inputs 2
  1207. channels rgb
  1208. uv rgb
  1209. filter impulse
  1210. name STMap1
  1211. xpos 180
  1212. ypos 350
  1213. }
  1214. set N7f77d000 [stack 0]
  1215. TimeBlur {
  1216. divisions {{"max(Transform1.size == 1 ? 2 : pow2(Transform1.size), 1)"}}
  1217. shutter 1
  1218. shuttercustomoffset {{"1 / divisions / 2"}}
  1219. name TimeBlur1
  1220. xpos 180
  1221. ypos 446
  1222. disable {{"parent.edge_blend_size < 1"}}
  1223. }
  1224. set N7f77cc00 [stack 0]
  1225. push $N7f77d000
  1226. Dot {
  1227. name Dot1
  1228. xpos -6
  1229. ypos 354
  1230. }
  1231. Difference {
  1232. inputs 2
  1233. name Difference1
  1234. xpos -40
  1235. ypos 440
  1236. }
  1237. Expression {
  1238. channel0 {none none none rgba.alpha}
  1239. expr0 "a > 1e-10"
  1240. channel1 none
  1241. channel2 none
  1242. channel3 none
  1243. name Expression1
  1244. xpos -40
  1245. ypos 494
  1246. }
  1247. Blur {
  1248. channels alpha
  1249. size {{parent.parent.edge_blend_size}}
  1250. name Blur2
  1251. xpos -40
  1252. ypos 536
  1253. }
  1254. Grade {
  1255. channels alpha
  1256. blackpoint 0.5
  1257. white_clamp true
  1258. name Grade2
  1259. xpos -40
  1260. ypos 584
  1261. }
  1262. Dot {
  1263. name Dot2
  1264. xpos -6
  1265. ypos 666
  1266. }
  1267. push $N7f77cc00
  1268. Grade {
  1269. inputs 1+1
  1270. white 1.4
  1271. black_clamp false
  1272. name Grade1
  1273. xpos 180
  1274. ypos 662
  1275. disable {{"parent.edge_blend_size < 1"}}
  1276. }
  1277. Merge2 {
  1278. inputs 2
  1279. Achannels rgb
  1280. Bchannels rgb
  1281. output rgb
  1282. name Merge1
  1283. xpos 180
  1284. ypos 758
  1285. disable {{!parent.overlay_pattern}}
  1286. }
  1287. Assert {
  1288. expression {{"Expression3.maxx > Expression3.minx && Expression3.maxy > Expression3.miny"}}
  1289. message "increase sample box size or decrease cell size"
  1290. name error
  1291. xpos 180
  1292. ypos 854
  1293. }
  1294. Output {
  1295. name Output1
  1296. xpos 180
  1297. ypos 950
  1298. }
  1299. end_group
  1300. Multiply {
  1301. inputs 1+1
  1302. channels rgb
  1303. value 1.8
  1304. maskChannelMask {{{parent.Merge9.maskChannelMask}}}
  1305. invert_mask {{!Merge9.invert_mask}}
  1306. name Multiply7
  1307. xpos 70
  1308. ypos 2315
  1309. disable {{"!maskChannelMask || !\[exists parent.input3.name]"}}
  1310. }
  1311. Dot {
  1312. name Dot23
  1313. xpos 104
  1314. ypos 2391
  1315. }
  1316. push $N7ff3d000
  1317. push $N7f28ec00
  1318. Multiply {
  1319. inputs 1+1
  1320. channels rgb
  1321. value 1.8
  1322. maskChannelMask {{{parent.Merge9.maskChannelMask}}}
  1323. invert_mask {{parent.Merge9.invert_mask}}
  1324. name Multiply2
  1325. xpos 290
  1326. ypos 2315
  1327. disable {{"!maskChannelMask || (!parent.scatter && !parent.external_grain)"}}
  1328. }
  1329. Merge2 {
  1330. inputs 2+1
  1331. operation copy
  1332. Achannels rgb
  1333. Bchannels rgb
  1334. output rgb
  1335. maskChannelMask -rgba.alpha
  1336. name Merge9
  1337. xpos 290
  1338. ypos 2387
  1339. disable {{"!(parent.scatter || parent.external_grain)"}}
  1340. }
  1341. Dot {
  1342. name Dot11
  1343. xpos 324
  1344. ypos 2490
  1345. }
  1346. set N7fb90c00 [stack 0]
  1347. MergeExpression {
  1348. inputs 2
  1349. temp_name0 reverse
  1350. temp_expr0 "1 / MergeExpression1.temp_expr0"
  1351. expr0 "Br * Ar * reverse"
  1352. expr1 "Bg * Ag * reverse"
  1353. expr2 "Bb * Ab * reverse"
  1354. name MergeExpression2
  1355. xpos 290
  1356. ypos 2654
  1357. }
  1358. Dot {
  1359. name Dot8
  1360. xpos 324
  1361. ypos 2850
  1362. }
  1363. push $N7ff3e800
  1364. Merge2 {
  1365. inputs 2
  1366. operation plus
  1367. bbox B
  1368. Achannels rgb
  1369. Bchannels rgb
  1370. output rgb
  1371. name Merge3
  1372. xpos 950
  1373. ypos 2846
  1374. }
  1375. Dot {
  1376. name Dot42
  1377. xpos 984
  1378. ypos 3018
  1379. }
  1380. set N7fb33800 [stack 0]
  1381. OCIOColorSpace {
  1382. in_colorspace {{OCIOColorSpace1.out_colorspace}}
  1383. out_colorspace {{OCIOColorSpace1.in_colorspace}}
  1384. name OCIOColorSpace4
  1385. xpos 950
  1386. ypos 3086
  1387. }
  1388. Dot {
  1389. name Dot19
  1390. xpos 984
  1391. ypos 3162
  1392. }
  1393. set N7fb32c00 [stack 0]
  1394. Dot {
  1395. name Dot41
  1396. xpos 1204
  1397. ypos 3162
  1398. }
  1399. set N7fb32800 [stack 0]
  1400. Dot {
  1401. name Dot36
  1402. xpos 1314
  1403. ypos 3162
  1404. }
  1405. Blur {
  1406. channels rgb
  1407. size 1
  1408. name Blur1
  1409. xpos 1280
  1410. ypos 3254
  1411. }
  1412. push $N7fb32800
  1413. Merge2 {
  1414. inputs 2
  1415. operation difference
  1416. bbox B
  1417. Achannels rgb
  1418. Bchannels rgb
  1419. output rgb
  1420. name Merge10
  1421. xpos 1170
  1422. ypos 3254
  1423. }
  1424. Multiply {
  1425. channels rgb
  1426. value 50
  1427. name Multiply3
  1428. xpos 1170
  1429. ypos 3302
  1430. }
  1431. Dot {
  1432. name Dot43
  1433. xpos 1204
  1434. ypos 3402
  1435. }
  1436. push $N7ff3f000
  1437. Dot {
  1438. name Dot45
  1439. xpos 1424
  1440. ypos -390
  1441. }
  1442. push $N7fb33800
  1443. Merge2 {
  1444. inputs 2
  1445. operation from
  1446. Achannels rgb
  1447. Bchannels rgb
  1448. output rgb
  1449. name Merge11
  1450. xpos 1390
  1451. ypos 3014
  1452. }
  1453. Dot {
  1454. name Dot46
  1455. xpos 1424
  1456. ypos 3522
  1457. }
  1458. push $N7fb90c00
  1459. Dot {
  1460. name Dot14
  1461. xpos 104
  1462. ypos 2490
  1463. }
  1464. Dot {
  1465. name Dot12
  1466. xpos 104
  1467. ypos 3402
  1468. }
  1469. push $N8ca3c00
  1470. Dot {
  1471. name Dot47
  1472. xpos -556
  1473. ypos -390
  1474. }
  1475. push $N8ca1400
  1476. Merge2 {
  1477. inputs 2
  1478. operation from
  1479. Achannels rgb
  1480. Bchannels rgb
  1481. output rgb
  1482. name Merge12
  1483. xpos -590
  1484. ypos -202
  1485. }
  1486. Dot {
  1487. name Dot10
  1488. xpos -556
  1489. ypos 3522
  1490. }
  1491. push $N7fb32c00
  1492. Switch {
  1493. inputs 5
  1494. which {{output}}
  1495. name Output
  1496. xpos 950
  1497. ypos 3656
  1498. addUserKnob {20 User}
  1499. addUserKnob {4 output M {"regrained comp" "plate grain" "normalised grain" "adapted grain" "grain QC"}}
  1500. }
  1501. CopyMetaData {
  1502. inputs 2
  1503. mergeMode "Meta only"
  1504. name CopyMetaData1
  1505. xpos 950
  1506. ypos 3758
  1507. }
  1508. Output {
  1509. name Output1
  1510. xpos 950
  1511. ypos 3854
  1512. }
  1513. end_group
  1514. # Creation Time=Sun Apr 25 01:20:51 2021
  1515. # Creator=Martin