【Nuke教程】在Nuke中利用track信息创建自定义运动模糊

30 七月, 2014
442
5
[隐藏]

作为一个合成师,我们的日常任务之一是把元素例如(灰尘,烟,火,水等)素材融入我们的镜头之中。我们很少得到专门为我们镜头拍摄的正确素材,所以我们得依靠的预拍摄素材库(最大常用的还是AK大神那一套)。

存在的问题

无论多么丰富的素材库,这些素材都将被重新调整利用(重置时间,缩放等),以配合拍摄的素材。素材通常是利用拍摄高帧速率快速获得包含大量的小细节(溅水,灰尘阵阵,爆炸等),所以我们获得最大的细节,并在可以获得了重置时间更多选择。然而,这通常也给了我们一个不自然的清晰的图像,由于快速的快门时间,所以我们经常要人为地增加运动模糊匹配到我们所合成的素材中。

给素材增加运动模糊

Nuke具有增加运动模糊的图像的几种方法。让我们快速回顾这些节点,并解释他们的具体问题。
Frameblend节点
使用frameblend廉价的方式大致模拟运动模糊。这可以帮助顺利重置素材时间,但如果画面是快速移动会留下“鬼影”效果,制作的小颗粒看起来像虚线。

frameblend_demo01

Optical Flow节点
另一种选择是使用类似OFlow,Kronos或RealSmart MotionBlur的节点,所有都使用相同的基础技术——光流。这是分析所述像素中的图像序列,并计算由帧的相对运动的帧的处理。所得到的运动矢量,可以使用重新定时录像时重新创建丢失的帧,或产生仅应用于图像的特定运动区域的运动模糊。

oflow_demo01

Optical Flow的工作方式类似的2D跟踪,它看起来在像素可识别的模式,并试图寻找下一个帧相同的模式。只有光流这是否在整个图像帧中跟踪所有的运动。只要在我们的镜头中有一致的纹理,系统可以计算运动的一个相当不错的结果。但如果图像每帧都变化很大,你可以结束工件未计算的轨道。

oflow_demo02

有一件事,Optical Flow真正斗争的是小颗粒镜头。虽然人类的眼睛可以在画面的整体运动分析的一个很好的工作,如果特征都非常相似(在飞溅的水滴,灰尘颗粒在爆炸)然后OFlow不知道哪些粒子是当它检查下一帧。

tracking_particles_demo01

Vector Blur节点
如果我们的素材是由3D程序渲染,通常会渲染另外一个运动矢量层。运动矢量层(也叫速度层)是一个渲染的图像表示每个像素的移动速度。红色,绿色和蓝色通道所包含的值并不代表可见的颜色,而是速度(X,Y和Z)。
当渲染图像的3D程序,这使它没有运动模糊的往往是有益的,在合成中通过使用运动矢量层和vectorblur节点给素材添加运动模糊并可以控制运动模糊大小。

CG_vector_blur02

我们很多时候不是渲染的3D图像的素材,我们没法很方便的去渲染运动矢量层。所以需要想出一个办法,我们可以人为地创造一个运动矢量层。
MotionBlur2D节点
该motionblur2d节点将以一个Transform节点跟踪数据,生成一个运动矢量层,然后可以驱动一个vectorblur。在此的限制是,该运动矢量的数据具有在整个图像中的单个值,所以模糊是相同量的无处不在。这对于匹配由相机移动产生的动态模糊,但如果拍摄中的不同元素都在朝不同的方向。然而,它给了我们一个基础去创建手动的运动模糊方案。

最好的手动运动模糊解决方案

现在,让我们陷入到一个实际的拍摄并使用这个素材库中水溅元素。我们会忽略重置时间现在假设我们只需要增加运动模糊匹配另一个素材。在不同的方向移动的液滴,但一般都遵循相同的抛物线拱在局部区域。

water_splash01a

大致的方法是使用motionblur2d以转换数据并从中计算运动矢量层的方法。诀窍是制约这一特定区域而不是整个图像,然后结合许多不同的变换表示图像的不同部分。
首先,我们创建了几个Transform节点和手跟踪一些较大的水滴。液滴形状改变整个拍摄,有时消失了几帧,但只要我保持变换遵循它们的运动规律将就足够了。

custom_tracker_hand_tracks01

现在创建一个基于颜色的速度。我选择一个Transform 节点和创建一个相应的Radial 节点。第一件事是创建一个自定义的2D位置旋钮在径向称为“position”利用表达它链接到Transform节点。

radial_position01我用的Transform节点的“center”,加上“translate”的值,给我一个绝对的(而不是相对的)在屏幕上的位置。

parent.Transform15.translate+parent.Transform15.center

在这里补充另一个自定义旋钮被称为“radius”,我设置为100像素为默认值,然后链接的表达在宽度值“radius”的径向的“area”的值,以绘制一个围绕“position”的值为中心的圆。

radial_area01

接下来,添加一个名为“velocity”的表达链上另外一个自定义的旋钮,它的值设置为“position”。

radial_position01

为此,我看“position”值当前帧(“T”),并从之前的帧中减去的值(“T-1”)。这使我象素的变换已经移动一帧,或者换句话说其速度的数目。

position(t)-position(t-1)

最后工作环节把“red”与“green”通道链接到径向的“color”值来表示速度。

radial_colour01

这个大概是我们需要——局部运动矢量通过一个特定的液滴。

radial_output01

我现在需要重复这个过程对于其他Transform轨迹。我复制的Radial和expression链接每个新节点到相应的Transform。然后,我用一个Merge添加所有的输出在一起。

custom_vector_blur_nodes02

如果我们看看结果,你会看到一个基本的速度矢量层,其中的值对应于每个跟踪点的运动。你会注意到一些地区的速度输出负值如滴右向左移动或向下。

radial_output02

但是,如何在最大填充间隙?当然,我们并没有这样做对于整个板块的每滴。 为什么我确信,因为每个径向有alpha值为1,所以我可以用Colour_Smear.gizmo来快速填充。
Colour_Smear.gizmo下载地址:


首先,我们采用一个300像素Blur整个图像。

radial_output03

…然后unpremultiply结果。这种扩散的值出来并平均值为空白。

radial_output04

最后总结

让我们来看看这现在效果。从新的RGB值到我们的水溅素材的“motion”通道,再添加一个Vectorblur节点,并告诉它从“motion”通道使用的值。

custom_vector_blur_nodes01

正如你所看到的,最终的结果是非常顺利。

water_splash02

尽管朝不同方向上的水滴,我们得到一个不错的运动模糊的正确匹配的速度。我调节模糊值相当高,使其很容易看到。我们可以增加/通过调整“multiply”旋钮矢量模糊节点上减少了。如果我们把它比作一个最好的方法(低),效果要好得多,因为他们缺乏假象。

custom_vector_blur_details01

最终效果预览

最后回顾一下

有一些事情,我们现在可以做的是完善我们的设置。
首先,的速度表达式只能看着是导致当前时刻的运动(即先前帧和当前帧之间究竟发生了什么),所以这就相当于我们在快门偏移设置为“end”,在一个正常的运动模糊。我将添加两个速度的计算。一个叫“velocity_start”会比较值对当前帧的下一帧的值(相当于我们的快门偏移设置为“start”)。

position(t+1)-position(t)

第二手柄,标有“velocity_centered”将在双方的“start”和“end”的速度,并创建一个它们之间的平均值,这就等同于让我们的快门偏移设置为“centered”。

((position(t+1)-position(t))+(position(t)-position(t-1)))/2

接下来,我将把的Radial打成在名为“vector_module”Group内,并调整表达式链接到任何转换插在本组的输入节点。这使得更新vector_module方便,你不需要硬编码要链接到Transform节点的名称,只需将其插入使用。 其好处是,现在你也可以插入一个跟踪节点(或实际上是输出“translate”和“center”值的任何节点)。我也感动了“radius”值来对本组的滑块,因为这是现在你可能需要手动调整的唯一值,并增加了一个下拉菜单,选择其中的快门偏移使用。

vector_module_nodes01

最后,我做了很多考虑是否使用“plus”运算符来合并所有vector_modules在一起的是正确的。那里有很多跟踪器在镜头开始重叠时,速度值变得无法自然就高了做,要添加的值加在一起的累加结果。我没有研究使用MergeExpression节点来解决这个问题,它使用下面的表达式。

Ar>0&&Br>0?max(Ar, Br):Ar<0&&Br<0?min(Ar, Br): (Ar+Br)

因此,如果从A和B素材的值都是正的,它会发现“max”,如果他们都是消极的,将找到“min”,如果他们是一个组合(或一个值是0),那么它将“plus”它们代替。
不过,我运行一些测试后,300像素模糊的运用和结果的差别几乎是感觉不到的。因此,我保持在一个标准的Merge,因为我可以将许多输入到一个单一的节点。

最后打包gizmo下载或者直接粘贴下面代码到Nuke中

Group {
 name vector_module
 help "For creating a custom motion vector pass based on translate data. Plug in a Transform or Tracker node that corresponds to a specific moving area of your image. Merge multiple instances of the vector_module together to create a motion vector pass.\n\nSee http://richardfrazer.com/tools-tutorials/custom-motion-vector-blur-using-trackers for a full tutorial."
 selected true
 xpos -673
 ypos 2300
 addUserKnob {20 User}
 addUserKnob {4 shutter M {centred start end ""}}
 addUserKnob {7 master_radius R 1 1000}
 master_radius 210
 addUserKnob {26 ""}
 addUserKnob {26 credit l "" +STARTLINE T "Vector Module v1.0 by Richard Frazer www.richardfrazer.com"}
}
 Input {
  inputs 0
  name transform_2d
  xpos -313
  ypos -386
 }
 Shuffle {
  red black
  green black
  blue black
  alpha black
  name Shuffle1
  xpos -313
  ypos -298
 }
set N310a8a10 [stack 0]
 Radial {
  area {{position.x-radius i} {position.y-radius i} {position.x+radius i} {position.y+radius i}}
  color {{parent.shutter==1?vector_start.x:parent.shutter==2?vector_end.x:vector_centred.x i} {parent.shutter==1?vector_start.y:parent.shutter==2?vector_end.y:vector_centred.y i} 0 1}
  name Radial1
  xpos -313
  ypos -200
  addUserKnob {20 User}
  addUserKnob {7 radius R 1 100}
  radius {{parent.master_radius i}}
  addUserKnob {12 vector_centred}
  vector_centred {{((position(t+1)-position(t))+(position(t)-position(t-1)))/2 i} {((position(t+1)-position(t))+(position(t)-position(t-1)))/2 i}}
  addUserKnob {12 vector_start}
  vector_start {{position-position(t-1) i} {position-position(t-1) i}}
  addUserKnob {12 vector_end}
  vector_end {{position(t+1)-position i} {position(t+1)-position i}}
  addUserKnob {12 position}
  position {{parent.input0.center.x+parent.input0.translate.x i} {parent.input0.center.y+parent.input0.translate.y i}}
 }
 CheckerBoard2 {
  inputs 0
  name CheckerBoard1
  xpos -148
  ypos -195
 }
 Switch {
  inputs 2
  which {{"parent.input0.name +1"}}
  name Switch3
  xpos -313
  ypos -100
 }
 Output {
  name Output1
  xpos -313
  ypos 27
 }
push $N310a8a10
 Viewer {
  input_process false
  near 0.9
  far 10000
  name Viewer1
  xpos 30
  ypos -247
 }
end_group

感谢richard frazer给我们带来如此精彩的教程。

本文转载于:ichardfrazer.com  翻译整理:weijer