Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
OpticalZDefocus is a physically accurate ZDefocus, which controls circle of confusion (coc) size based on lens geometry using the depth of field equation. Set your lens and film-back characteristics, your focus distance, and adjust the size of your bokeh with the aperture size, just like a real lens.
set cut_paste_input [stack 0]
push $cut_paste_input
Group {
name OpticalZDefocus
help "<b>OpticalZDefocus</b> is a physically accurate ZDefocus, which controls circle of confusion (coc) size based on lens geometry using the depth of field equation. \n\nSet your lens and film-back characteristics, your focus distance, and adjust the size of your bokeh with the aperture size, just like a real lens."
tile_color 0xcc804eef
addUserKnob {20 OpticalZDefocus}
addUserKnob {41 channels T _ZDEFOCUS_.channels}
addUserKnob {41 useGPUIfAvailable l "Use GPU if available" T _ZDEFOCUS_.useGPUIfAvailable}
addUserKnob {26 ""}
addUserKnob {41 depth_channel l "depth channel" t "Choose the channel that contains your Z-Depth" T CHANNEL_CHOOSER_DEPTH.Zchan}
addUserKnob {26 spacer l " &nbsp; &nbsp; " -STARTLINE T " "}
addUserKnob {6 unpremult_z l " &nbsp; &nbsp; <b>unpremult</b> by" t "Unpremultiply the depth layer by the selected channel" -STARTLINE}
addUserKnob {41 depth_alpha l "" -STARTLINE T CHANNEL_CHOOSER_ALPHA.Zchan}
addUserKnob {22 set_z l "Sample Z" t "Sets the focal distance to the Z channel value at the current focal point on the current frame." T "from __future__ import with_statement\n\nn = nuke.thisNode()\ns = n\['s']\nz_coord = n\['sample_z']\n\nwith n:\n ds = nuke.toNode('DepthSampler')\n zsample = ds.sample('red', z_coord.getValue(0), z_coord.getValue(1))\n\nif s.isAnimated():\n s.setValueAt(zsample, nuke.frame())\nelse:\n s.setValue(zsample)" +STARTLINE}
addUserKnob {12 sample_z l "&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sample position: " t "Allows you to sample the Z channel at a specific 2d position." -STARTLINE}
sample_z {250 250}
addUserKnob {4 depth_unit l "depth unit" t "Set the unit of your zdepth." M {mm cm dm m inch ft}}
depth_unit dm
addUserKnob {26 spacer2 l "" t " " -STARTLINE T " "}
addUserKnob {6 show_coc l "show coc" t "Output the calculated direct circle of confusion size map that is used to drive the ZDefocus in direct mode.\n\nUseful for troubleshooting." -STARTLINE}
addUserKnob {26 divider l " " T " \n"}
addUserKnob {7 s l "focus distance" t "Set the focus distance" R 10 1000}
s 25
addUserKnob {26 ""}
addUserKnob {41 constant_defocus l "constant defocus" t "If enabled, depth-varying defocus is disabled and defocus amount is controlled directly by the max defocus slider." T _ghost_whisper_.constant_defocus}
addUserKnob {41 max_size l "max defocus" t "Set the max defocus size allowed" T _ZDEFOCUS_.max_size}
addUserKnob {7 min_zdepth l "min zdepth" t "If ZDepth = 0, ZDepth will be set to the specified value.\n\nThe ZDefocus node can be very slow to calculate if you have zero values in your zdepth, for example if you have areas that have transparent alpha. \n\nSet min zdepth to a value slightly smaller than the nearest object in your scene to speed up processing time." R 0 20}
min_zdepth 1
addUserKnob {26 ""}
addUserKnob {26 focal_params l "<b>lens geometry" t "Set the focus parameters here. These are overriden if there is a camera node connected to the 'Cam' input." T " "}
addUserKnob {22 get_selected_camera l "Get Selected Camera" t "Set the parameters using the selected camera." T "from __future__ import with_statement\n\ndef get_camera():\n ozdef = nuke.thisNode()\n with nuke.root():\n cam = nuke.selectedNodes()\n if len(cam) != 1:\n nuke.message('Please select a single camera node.')\n return\n elif len(cam) == 0:\n nuke.message('Please select a single camera node.')\n return\n else:\n cam = cam\[0]\n if 'Camera2' not in cam.Class():\n nuke.message('Please select a camera node.')\n return\n ozdef\['f'].setValue(cam\['focal'].getValue())\n ozdef\['N'].setValue(cam\['fstop'].getValue())\n ozdef\['haperture'].setValue(cam\['haperture'].getValue())\n\nif __name__ == \"__main__\":\n get_camera()" +STARTLINE}
addUserKnob {7 f l "focal length" t "Set the focal length of the camera" R 0 500}
f 50
addUserKnob {7 N l f-stop R 0 44}
N 4
addUserKnob {7 haperture t "Horizontal aperture of the film-back / sensor" R 0 50}
haperture 24
addUserKnob {26 ""}
addUserKnob {41 autoLayerSpacing l "automatic layer spacing" T _ZDEFOCUS_.autoLayerSpacing}
addUserKnob {41 layers l "depth layers" T _ZDEFOCUS_.layers}
addUserKnob {41 layerCurve l "layer curve" T _ZDEFOCUS_.layerCurve}
addUserKnob {20 Filter}
addUserKnob {41 filter_type_1 l "filter type" T _ZDEFOCUS_.filter_type}
addUserKnob {7 aspect_ratio R 0 2}
aspect_ratio 1
addUserKnob {7 filter_shape}
filter_shape 1
addUserKnob {3 blades}
blades 9
addUserKnob {7 roundness}
roundness 0.2
}
Input {
inputs 0
name Input
label "\[value number]"
xpos -308
ypos 64
}
Dot {
name _ghost_whisper_
knobChanged "\nk = nuke.thisKnob()\nn = nuke.thisNode()\nif k.name() == 'constant_defocus':\n is_const = n\['constant_defocus'].getValue()\n knob_list = \['min_zdepth', 'get_selected_camera', 'f', 'N', 'haperture', 'scale']\n nuke.root().begin()\n parent_node = nuke.toNode(n.fullName().split('.')\[0])\n for knob in knob_list:\n knob = parent_node\[knob]\n if is_const:\n knob.setEnabled(False)\n else:\n knob.setEnabled(True)\n"
tile_color 0x129000ff
note_font_size 42
note_font_color 0x7f7f7f01
xpos -274
ypos 114
addUserKnob {20 User}
addUserKnob {6 constant_defocus +STARTLINE}
}
set N3456ccb0 [stack 0]
Dot {
name Dot7
note_font_size 42
note_font_color 0x7f7f7f01
xpos -542
ypos 114
}
AddChannels {
channels depth
channels2 rgba
name AddChannels1
xpos -576
ypos 144
}
set N31b2a9f0 [stack 0]
push $N31b2a9f0
Copy {
inputs 2
from0 {{{CHANNEL_CHOOSER_DEPTH.Zchan}}}
to0 rgba.red
from1 {{{CHANNEL_CHOOSER_ALPHA.Zchan}}}
to1 rgba.alpha
bbox B
name _CHOOSE_CHANNELS_
xpos -576
ypos 218
disable {{hasError}}
}
set N2fd651c0 [stack 0]
Unpremult {
name _UNPREMULT_Z_
xpos -576
ypos 310
disable {{!parent.unpremult_z}}
}
Multiply {
channels rgb
value {{"parent.depth_unit == 1 ? 10 : parent.depth_unit == 2 ? 100 : parent.depth_unit == 3 ? 1000 : parent.depth_unit == 4 ? 25.4 : parent.depth_unit == 5 ? 304.8 : 1"}}
name _UNIT_MULTIPLIER_
xpos -576
ypos 390
addUserKnob {20 User}
addUserKnob {7 depth_unit_divider R 0 500}
depth_unit_divider {{"parent.depth_unit == 1 ? 10 : parent.depth_unit == 2 ? 100 : parent.depth_unit == 3 ? 1000 : parent.depth_unit == 4 ? 25.4 : parent.depth_unit == 5 ? 304.8 : 1"}}
}
Expression {
temp_name0 zdepth
temp_expr0 "r < parent.min_zdepth* _UNIT_MULTIPLIER_.value ? parent.min_zdepth* _UNIT_MULTIPLIER_.value : r"
temp_name1 focus_dist
temp_expr1 "s * _UNIT_MULTIPLIER_.value"
temp_name2 coc
temp_expr2 "(fabs(focus_dist - zdepth) * pow(f,2) / (N * zdepth * (focus_dist - f)))"
temp_name3 coc_px
temp_expr3 "fabs(coc / haperture * input.width / 2)"
channel0 rgba
expr0 "parent.constant_defocus ? parent.max_size : coc_px"
channel1 none
name Generate_Direct_Z
xpos -576
ypos 430
addUserKnob {20 Optical l "Optical Characteristics"}
addUserKnob {6 input_cam t "True if there's a camera connected" +STARTLINE}
input_cam {{"\[exists parent.input2]"}}
addUserKnob {7 f l "focal length" R 0 500}
f {{"input_cam ? i_f : parent.f"}}
addUserKnob {7 N l f-stop R 0 44}
N {{"input_cam ? i_N : parent.N"}}
addUserKnob {7 haperture R 0 50}
haperture {{"input_cam ? i_haperture : parent.haperture"}}
addUserKnob {7 s l "focus distance" R 0 1000}
s {{parent.s}}
addUserKnob {7 scale t "Divide the value by this. For example of the scene Z-depth is measured in meters, you may need to set this to 1000" R 1 1000}
scale {{parent.scale}}
addUserKnob {26 ""}
addUserKnob {7 i_f R 0 500}
addUserKnob {7 i_N R 0 44}
addUserKnob {7 i_haperture R 0 50}
addUserKnob {7 i_s R 0 1000}
}
Dot {
name Dot3
note_font_size 42
note_font_color 0x7f7f7f01
xpos -542
ypos 514
}
set Nfb0dda00 [stack 0]
Dot {
name Dot2
note_font_size 42
note_font_color 0x7f7f7f01
xpos -542
ypos 794
}
Input {
inputs 0
name InputFilter
label "\[value number]"
xpos 94
ypos 144
number 1
}
Reformat {
type scale
scale {{parent.aspect_ratio} 1}
resize distort
name _aspect_ratio_1
xpos 94
ypos 430
}
Dot {
inputs 0
name Dot1
label " Default Filter Input"
note_font "Helvetica Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold"
note_font_size 24
note_font_color 0xff000000
xpos 262
ypos 314
}
Reformat {
type "to box"
box_fixed true
name Reformat1
xpos 228
ypos 390
}
Flare {
position {{width/2} {height/2}}
radius {75 88 91}
inner_color 1
name Flare3
xpos 228
ypos 430
}
Reformat {
type scale
scale {{parent.aspect_ratio} 1}
resize distort
name _aspect_ratio_
xpos 228
ypos 470
}
Shuffle {
alpha red
name Shuffle1
label "\[value in]"
xpos 228
ypos 504
}
Switch {
inputs 2
which {{"\[exists parent.input1]"}}
name Switch3
xpos 94
ypos 510
}
Dot {
name Dot6
label " "
note_font "Helvetica Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold Bold"
note_font_size 24
note_font_color 0xff000000
xpos 128
ypos 594
}
push $Nfb0dda00
push $N3456ccb0
add_layer {opticalzdefocus opticalzdefocus.Z}
Copy {
inputs 2
from0 rgba.red
to0 opticalzdefocus.Z
bbox B
name _Copy_ZDepth_
xpos -308
ypos 504
}
ZDefocus2 {
inputs 2
channels rgba
z_channel opticalzdefocus.Z
math direct
focal_point {16540 12700}
size 1
max_size 100
legacy_resize_mode false
show_legacy_resize_mode false
use_input_channels true
aspect {{parent.aspect_ratio}}
blades {{parent.blades}}
roundness {{parent.roundness}}
inner_feather 0.28
catadioptric_size 0.375
name _ZDEFOCUS_
xpos -308
ypos 584
}
Remove {
channels opticalzdefocus
name Remove1
xpos -308
ypos 664
}
Switch {
inputs 2
which {{parent.show_coc}}
name _SHOW_COC_
xpos -308
ypos 790
}
Output {
name Output1
xpos -308
ypos 1030
}
push $N2fd651c0
NoOp {
name DepthSampler
xpos -710
ypos 230
addUserKnob {20 User}
addUserKnob {7 sval R 0 1000}
}
ZBlur {
inputs 0
channels rgba
shape 1
name CHANNEL_CHOOSER_DEPTH
xpos -442
ypos 230
disable true
}
ZBlur {
channels rgba
Zchan rgba.alpha
shape 1
name CHANNEL_CHOOSER_ALPHA
xpos -442
ypos 272
disable true
}
end_group
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment