RealFlow 翻译教程之——破裂的肥皂泡(-)

肥皂泡每个人都吹过,甚至成人也会很有兴趣的玩,还尝试玩出不同花样。除了好玩,肥皂泡还有一些非常有趣的科学背景。

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地
图1.一个真实的肥皂泡(图片出自 Mila Zinkova,发布在GUN,我是在维基百科找到的)

 

表面张力或许是肥皂泡最重要的一个特性了。因为表面张力的存在,这也是肥皂泡会在空气中摇摆不定的原因。另一个由表面张力产生的效果是,肥皂泡是球形的。假如没有外部环境(重力,空气阻力等等),肥皂泡将是一个完美的球形。因为它们总有形成,称为极小曲面(minimal surface)的趋向。

 

你一开始看到肥皂泡,你可能会认为它有很高的表面张力,其实正好相反。肥皂和洗涤剂表面张力很低,如果不是这样肥皂泡就不会产生了。因为水的表面张力很高,肥皂泡会立即破裂。

 

另一个让人印象深刻的是肥皂泡很漂亮。它总是有很多颜色,他们反射的颜色看起来在晃动,混合了油一样。肥皂泡有这么的丰富颜色,因为它的壁很薄。当水蒸发时(肥皂泡变薄),会有不太显眼的颜色。当然这个效果不能用RealFlow模拟。但可以用物理渲染引擎做到,让它看起来五颜六色。在渲染时你可以调节材质的不同厚度,得到不同颜色。

 

第一步:怎么在RealFlow里创建一个泡泡

 

第一步就是创建泡泡。在这个例子里,填充模型做泡泡,不是一个好方法,因为它要一个尽可能薄的空心物体。用单个粒子层可以达到这个目的。在RealFlow里有这样几种方法来做成这种结构:

 

1把.粒子均匀分布的Python脚本

2.“sphere”发射器

3.“Fill Object”发射器和“k sphere”辅助器结合

4.激活“Particle layer”设置的“Fill Object”发射器

 

第一个方法能给你很好的效果,因为你能得到一个没有任何缝隙或孔洞的球体。但用粒子脚本是有问题的。原因是每一个粒子有一个确定的基于Resolution值的半径。

这半径是很重要的,因为为直接影响粒子之间的力。如果粒子之间距离非常近,你会观察到互相排斥的效果,流体会变得不稳定。也可以用非常低的内压“Int Pressure”参数减少这排斥值,但那时就会失去流体的特性看起来像dumb粒子。 这所以是Dumb粒子,当然就是因为非常低的”Int Pressure“值。

 RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 图2:分布规则的球体

 

你可以降低“Resolution”值,但不容易找到正确的值。如果太高,很难与粒子交互;太低,流体粒子就会乱飞。

 

第二个方法是使用“Sphere”发射器。用这个方法也可以创建一个很薄的粒子层。你仅仅需要把"speed"值设成很低,例如 0.1 。然后第一帧后停止发射。这样可以管理表达式或动画关键帧。

 

可能最好的方法就是基于"Fill Object"发射器。这发个发射器提供了两种模式:第一个模式是填充模型。填充好后你可以把“k volume”辅助器放在模型里面(“Inverse=Yes”),删除多余的粒子。当然辅助器半径可以做些调整,根据空心的模型来调。结果还不错,但你可以在下面的图片看到,看起来像有花纹的图案。这方法可以轻松控制厚度并能根据需要,用大量粒子。

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

图3.用"Fill Object"发射器填充的空心球粒子,辅助使用"K Sphere"辅助器

 

然后,用“Fill Object”第二种模式:“Particle layer”(粒子层)。当这个设置为“Yes”,RealFlow会覆盖满球体表面,但不会出现几何体交接线。优点是流体是静止的,因为这是RealFlow自动计算正确粒子半径,你可以增加“Resolution”到非常高的值,而不会出错。它也能减少粒子间缝隙,你只是需要一个很高分辨率的球体/泡泡做基础。

 

用 RF_toolfactory’s “RF Toolbox Scripts”(最后一个教程会介绍这个工具)你可以重新创建很高分辨率的模型。

 

你可以在下面图片看到结果。请注意这是较低resolution值版本,忽略相邻边线。

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 这个方法另一个优点是:你不需要任何初始状态,因为粒子层是Realflow直接创建的,存储或改变时只要“Reset”一下就可以。

 

第二步:脚本

 

做这个效果的脚本是很短的,也很容易理解。在写脚本之前,很重要的一件事就是你要知道我们要做成什么效果。我想在粒子层上开一个渐渐扩大的洞。在这个过程中,流体其它部分必须不受影响,保持原样。

所以第一步就需要冻结所有粒子,然后把他们速度设置成0.0。再然后就开始定义,到底在泡泡哪个地方破裂。函数要允许我们把扩散的种子(seed)放在整个表面,或完美的限制他们在一个特定区域。这部分要在模拟前执行,尽管它是"Simulation Events"脚本:

 

Layout>Simulation Events

 

初始化场景

 

窗口弹出时,你会看到两个部分。上面部分是模拟事件分支,下面部分是Python 代码部分。脚本预设必须添加在”SimulationPre“:

 

SimulationPre > Right-click > Add script...(RF5版本后,Layout-->Simulation Events<Ctrl+F2>   打开下图3窗口)

 

此操作会打开另一个窗口,你可以输入脚本:

 

# Get the emitter, loop through its particles and freeze them

 

emitter = scene.getEmitter("Fill_Object01")

particleList = emitter.getParticles()

for particle in particleList:

  particle.freeze()

 

# Determine four seed particles which are relatively close together

 

idList = []

maxId = len(particleList)/50

for i in range(0,4):

  curId = random.randint(0, maxId)

  idList.append(curId)

scene.setGlobalVariableValue("oldRadius", 0.005)

scene.setGlobalVariableValue("idList", idList)

 

第一个代码片段只是简单的调用发射器和粒子。通过循环全所有粒子冻结用freeze()函数。这个函数功能是使粒子保持当前所有状态,例如,velocity和position.直接粒子不再锁定时。


 

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 

图3:初始化"Simulation Evets"窗口脚本 .

 

脚本第二部分是很有趣的,因为会定义种子(seed)。在这个例子,种子(seed)是产生随机。为此,脚本从“particleList”函数指定粒子的总数。要控制种子(seed)影响更多或更少区域,整个粒子数除以50.如果想靠近一点,可以除以100,或500,如除以1则遍布整个表面。接下来循环

 

for i in range(0,4):

 

用来创建4个种子粒子。如果你想要增多种子,只要简单的改变括号里第二个数字,例如(0,2)或(0,8)。结果是一个随机数,可以用来寻找一定的粒子,通过利用粒子的ID数。ID被存储起来供进一步使用。

 

最后,所有相关数据必须存储在被为全局变量的里面。这个变量是一种,当你想共享不同脚本(类型)下的值/变量(例如Batch -> SimulationPre, FramesPre -> StepsPost 等等)和当变量要永久存储(值固定)。全局变量是“oldRadius”和“idList”。这“idList”是,当然需要种子粒子ID。“oldRadius”变量决定种子粒子周围破裂的大小。它值要很小获得连续效果。它甚至可以是0.

 

模拟

 

第二部分是脚本控制模拟,在"FramesPre"下,在simulation events tree (模拟事件分支)。这里脚本输出和用粒子ID,和初始半径。另外,循环需要遍历整个粒子。当一个ID存在于“idList”,脚本就继续扩散到相关连粒子。

 

import random

 

# Prepare the variable, get the emitter and its particles

 

oldRadius        = scene.getGlobalVariableValue("oldRadius")

idList           = scene.getGlobalVariableValue("idList")

emitter          = scene.getEmitter("Fill_Object01")

particleList     = emitter.getParticles()

initialRadiiList = [0.005,0.009,0.015,0.012]

counter          = 0

 

# Loop through all particles, get Ids

for particle in particleList:

  theId = particle.getId()

 

  # Check if the current Id is in already stored in the idList.

  # If yes, calculate the radius around the seed particles.

 

  if theId in idList:

   newRadius = oldRadius + initialRadiiList[counter]

   neighbors = particle.getNeighbors(newRadius)

   counter  += 1

  

   # Replace the old radius with the new radius to simulate a grwoing area

   scene.setGlobalVariableValue("oldRadius", newRadius)

 

   # Loop through the particles around the seed and unfreeze its neighbours

   for neighbor in neighbors:

    if (neighbor.getId() in idList):

     particle.setVelocity(Vector.new(0,0,0))

    else:

     neighbor.unfreeze()

 

脚本思路是,收集种子(seed)粒子周围一定半径内相邻粒子。一旦种子(seed)识别出周围粒子,它就会解锁,然后(再次)受到辅助器和力影响。为了使破裂变得更有丰富,每个种子粒子有不一样的初始半径。这些半径存储在扩散列表:“initialradiiList”里。

 

要获得种子粒子周围渐渐增长区域,老的半径值(oldRadius)必须要被“newRadius”取代。这只能通过全局变量,因为这种类型,不会被清空,在模拟步骤执行后。

 

在此脚本计数器是必要的,从“initialRadiiList”不同的半径值分配到每个种子粒子:在脚本第一部分四个种子粒子已经设置了。所以必须要除以这四个半径值。如果ID找到,脚本会从这个列表中给出适当半径值,例如,半径值3的种子(seed)粒子:

 

initialRadiiList = [0.005,0.009,0.015,0.012]

[ ... ]

  if theId in idList:

   newRadius = oldRadius + initialRadiiList[2] # (= 0.015)

   neighbors = particle.getNeighbors(oldRadius + 0.015)

   counter  += 1 # Incement the counter to get the next radius value

 

 

请注意,Python列表总是从0开始,第三个位置在"initialradiList"数字是"2":0,1,2,3。

 

在这个阶段的脚本已经标出相关种子粒子和相邻粒子。现在完成遍历,相邻粒子,接受"unfreeze()"函数。但这是特别的。这里涉及到种子粒子,因为他们要保持接近他们的初始状态。想像一个种子粒子,受“Noise field”场影响,在泡泡表面。在这个例子里,脚本找不到相邻粒子就不会继续破裂,那会停止在某个点。为避免这个,每个种子粒子速度将要放缓:

 

if (neighbor.getId() in idList):

 particle.setVelocity(Vector.new(0,0,0))

发射器设置

设置发射器实际上只是简单的几个步骤。但在你开始往下做时,必须要在Global Links面板移除“sphere”结点,因为它很影响粒子。

 

为了在表面得到足够多粒子,很高的resolution是必要的。在这个场景"Resolution"值是 1000.0 对 2*2*2球体,有 5120个面。仍然会在粒子间看到一些边线,但做成mesh就看不到了。如果你要创建更多粒子,可以自由的改变这些值。你会看到模拟,仍然是很快的,尽管因为Python脚本,都是用单核模拟的。

 

为了要凸起的流体界线,“Ext pressure”要设置到5.这将有助于保持粒子靠近一起,避免粒子逃逸。

 

最后,“Surface tension”。代替发射器值,你可以用Surface tension辅助器(同名),激活“Balanced”设置,但这不是必须的。必要的是在“Surface tension”上key帧,让模拟结果更真实一点。在介绍真实的肥皂泡时,你知道真正的肥皂泡表面张力是很小的,但那只是自然界中,这是模拟。在RealFlow我们可以用各种方法模拟,达到想要的效果。因此设置时数值是否符合自然界中,是不重要的。要达到所需要的外观和形态时就要很高的“Surface tension”值,如果这值很低,泡泡就会毁掉。这是“Surface tension”动画曲线:

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 

 

 

动画区间在0到120帧间从 200降到50.曲线是“Bezier”类型,创建第一帧的过程中,泡泡几乎完好无损。

 

当你点击“Simulate”,现在你能在种子粒子周围区域看到逃逸的粒子,或不想要的效果。要避免这个,我建议你用更高的MIN substeps值,在25到50之间。它能保持一些加速的粒子。要保持速度稳定,就添加辅助器。

 

辅助器

 

要除去非常快的粒子和保持流体稳定,在场景里要用到三个辅助器:

 

1."k Isolated",这个辅助器除去孤立的粒子在 0.1秒后

2."K Speed"作用:粒子速度超过2.0就会被除去

3.”Drag force“这个辅助器把”Drag strength“调到5.0,有助于有一个合理的模拟环境和看起来更自然。

 

基于发射器设置,你可以调节辅助器参数,但要有一个好的起始点。

 

要使模拟更丰富,和得到漩涡,添加"Noise field"场。通常使用值 0.2,来模拟,但“Space scale”3.0获得的漩涡在更小的区域。最后辅助器是“Attractor”,要使排斥变得很小,"Internal force"值设为-0.1,来分散一点粒子。

 

你现在得到近似图片上的效果了吗:

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 

 

图4.粒子表达破裂的肥皂泡

 

在这图片你能清楚的看到不同的速度,但你的模拟可能只会显示一个统一的蓝色外观。要有不一样外观,到发射器”Display“面板,用下面的设置

 

Node Params > Display > Automatic range > No

 

Node Params > Display > Max range > 0.4

 

Mesh (网络)

 

所有的部分就是为了创建一个好的mesh。因为肥皂泡是非常易碎的,mesh要尽可能的薄。当然,mesh有一个确定的厚度,你不能创建一个单面的模型,或mesh仅是由一个面几何体构成。最终设置,是基于粒子数量和场景大小。

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 

 

 

 

在左边图片上泡泡有接近 92000个粒子。要圆滑几何体边线缝隙,“Smooth”值要被用到,除了减小filter值。用很低的"Polygon size"值可提供更多的细节,调高就会损失细节。

 

要得到很薄的表面,mesh的“field”设置必须调节。这里你可以看到“Radius”值。这参数决定了球体的半径(是指每个创建的粒子)。如果模拟不足,粒子值很小时,你就会看到缝隙和孔洞。因为球体上粒子不能互相接触到。当你粒子数量很小时,就要降低“Radius”,和减小mesh厚度。所以你如果想要一个非常薄的泡泡,就大大提高发射器的"Resolution"和减小mesh的“Radius”

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

 

 

图5.Field设置

 

接下来的图片,就是刚设的mesh结果,缝隙和孔洞,已经看不到了。粒子呈一串串,和一丝丝状,是由于很高的“surface tension”引起的。

RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地

一句话总结:

当当哐!Fill Object ,Prticle layer建泡泡

嚓咔咔!模拟事件脚本是关键,初始化场景,控制模拟进程

叽叽咕!发射器,辅助器,也要来帮忙

咂叭叭! mesh,mesh去渲染。

(不太押韵,有时间再修改,大家有好建议可以评论告诉我)

 

 

 

版权注意事项

 

所有在这文章中图片,文字,和素材都属于RF_toolfactory.你可以复制和分享这PDF,但不允许直接提供PDF下载。无论是在论坛,还是文件共享站,种子站或其它地方。但你可直接链接“simple Vortex”,进行交流的目的,是可以的。

 

所有已经给出的材料都做过最大的努力,但错误不能完全排除。RF_toolfactory不为计算机或软件崩溃和/或数据丢失负责。需要您自己承担使用本材料脚本,和文件在你硬盘上的风险。

 

不允许转卖PDF和素材。不允许删除版权信息。如果你用这PDF图片或文字到有其它目的,要标明出处。

 

“Simple Vortex” by RF_toolfactory (http://www.rf-toolfactory.com)

 

谢谢。

 

RealFlow 翻译教程之——破裂的肥皂泡(-)  

2011-11-25 01:02:47|  分类: RealFlow探索 |  标签:realflow  肥皂泡  免费教程  翻译  豆芽兵   |字号大中小 订阅

 
 
重要提示:12,12日 这个教程最终模拟时,第一遍会报错。Reset一下,再模拟就正常了。

具体原因解释请看问题总结日志:


内容简介:
RealFlow 翻译教程之——破裂的肥皂泡(-) - 豆芽兵 - 豆芽兵的天地
重要提示

 

在 2011.10.5号之前的PDF教程“Bursting Soap Bubble”,有一个错误。第二个脚本不能放在“StepsPre”,应放在“FramesPre”。非常感谢来自 孟买/印度(Mumbai/India)的朋友 Sukumar Senthil Raj,告诉我们这个错误。正确的教程已经放到下载栏了。

 

此免费教程教你怎样创建一个,在慢镜头中慢慢破裂肥皂泡的漂亮效果。用一点Python脚本就可以帮助你能,确定肥皂泡的不同表面区域破裂。一旦表达破开,效果就会波及整个泡泡。


 

 

虽然此效果可以不需要脚本,但为了更好的控制还是使用的好。

1.效果速度传播

2.可以轻松定义表面到底哪个区域破裂

3.当破裂产生就定义新的点

4.此效果不只限于肥皂泡,可用于任意开关

 

最后,创建这流体特殊效果要做的一些设置,仅仅是非常高的表面张力值(tension)。辅助器和力也很重要。当然要进行Mesh操作,另一个是原因是,因为我们想输出一个肥皂泡,最好也是用Mesh。你能在右边看到两个视频,第一个是在RealFlow里Mesh过的样子,第二个是输出渲染过的版本。

 

总之这个慢慢破裂的肥皂泡效果是非常可吸引人的,你可以加上其它设置,应用在不同场合,例如用kill辅助器做成,等离子球或融化效果。

 

展示出你的作品

 

当然一个教程只能是一种解决问题的方法,我们希望你多调调参数,力和动画曲线,并展示出你的实现方法。我们对你作的教程很感兴趣,你可以在网站上发静帧或给我们视频链接。


—— 郑州奇境视觉动画公司 收集整理 【中原专业视觉图像服务商-专注于建筑漫游动画施工演示动画,产品展示动画