RealWave (真实波浪面)

  RealWave 的曲面三角网格是可自定义的多边形。这种面可以变形和置换,用各种预定义的修饰美化(modifier)。Next Limit 公司 在RealFlow5增加了被称作 频率波(statistical spectrum wave)修饰美化波峰的模拟。

  这种波浪类型高度逼真,也非常有用。本次教程方法很容易,能快速和方便创建出波峰浪花而不用那些修饰美化(modifier 附加的效果)。因此这个教程也适用于RealFlow4.


  波峰浪花的本质

  波峰浪花可以在一些特别的天气条件下看到——如暴风雨。不同于波浪。只要一点点风,海洋表面就会出现波纹很小的波峰。另外,这些波浪有非常高的频率。这意味着两峰之间的距离非常小。



  在暴风雨期间,我们可以看到整个外观上的变化,但实际上我们只看到在大小上的改变。波浪变得更高,波长增加。一定高度的波浪甚至破碎。所有这些波有一个共同点:顶部的浪是尖锐的,底部是平整的。另一个影响波浪外形的因素是海洋的深度。理论上,波浪高度可达到海洋深度,但现实中波浪只有几米高。在风和浪潮的驱使下,浪花一波波的生成。在浪峰顶部和波浪低谷处经常能看到白色泡沫。


  计算机产生波浪

  用计算机有很多方法产生波浪,它们在质量和模拟时间上有很大不同。在游戏里,当然是性能重要,因为计算和交互都是实时显示的。因此这些波浪不能模拟太高的细节。

  对于大多数商业3D应用,是有专门波浪生成器的,这些工具有优秀的品质,模拟时间也适中。Jerry Tessendorf 的研究,是经典的生成高真实度波浪的方法。Tessendorf 用统计方法开发了基本思路,被用到很多软件和插件中。RealFlow的 (cresting wave modifier)也是基于Tessendorf的研究。

  (译者注:Jerry Tessendorf 某图形学专家,发表过很有影响力的论文 《Simulating Ocean Water》,google一下就能找到原文,值得深入学习)


  RealFlow中另一种方法是增加cresting wave到 RealWave mesh:使用Python 脚本操作。用这个方法能载入图片序列转换贴图,输出像素的颜色值,改变mesh.这个方法主要问题是,需要在其它软件创建转换贴图(displacement map)。

  这些转换背后的理念是,RealFlow能混合脚本波浪和其它修饰浪(modifier)或是与其它对像交互产生的浪。



  图1 在RealFlow5中的Statistical specturm (统计频率)波浪


  用Python辅助,你也能添加自己的公式到RealWave浪面。在RealFlow4 里使用脚本仅能影响面的高度轴,现在可以改变x,y和z三个轴。非常简单的方法是用用Gerstner wave (盖斯特纳波)给尖锐波浪。Gerstner,捷克数学家,开发出一个简单方法创建波浪。这种方法在RealFlow5得到了应用,但在之前版本不提供这一方法进行修饰(modifier)。

  Gerstner 波浪有免费的Python脚本在RF_tool factory网站。这个教程结果与RealFlow5相应功能做出来是完全相同的,但用这个脚本,你会理解如何使用公式创建属于自己的波浪类型。


  怎样创建 cresting wave (浪峰波浪)

  最后,我们讨论下创建自己的波浪面。打开RealFlow,新建一个工程,选择:

  Edit > Add > RealWave

  在这个步骤后,我们会在Node面板看到一个新的RealWave对像。保持默认值,但为了看的清楚,教程里Polygon size值调为0.05.对于大型海洋表面,只要缩放RealWave节点就好了。现在右击RealWave对像选择

  Nodes > RealWave01 > Right-click > Add Wave... > Spectrum

  新的形变对像立刻在RealWave对像下生成。当点击“Spectrum”对像,你可以访问新的面板,在Node Param (节点参数)。若要找到相关设置,得到浪峰外观,从"Sinusoidal"改变成“Shape”参数然后模拟。这里就是你得到的:



  第一个结果能看到这个漂亮的锐利的外观,但表面上仍缺乏细节,需要更高的波峰和加大多样性。频率(frequency),采样(sample)和缩放(scale)参数有助于我们更好的模拟。



  核心设置是“Min,frec”和“Max,frec”。这些参数不能改变太多,因为他们种类广泛的,更小和更大波浪。给定的频率(frequencie)范围频谱(spectrum)。


  脚本参数

  本节只讲解创建浪峰波浪相关参数。


  Shape

  这个选项提供了三个设置:“Sinusoidal”,"Asymmetric",和“Sharp”."Sinusoidal"类型基本上是增加正弦函数,“Asymmetric”设置看起来更自然些。在这个场景“Sharp”要被用到。


  Min.frec./Max.freq.

  这是波浪(spectrum)的频率范围。用非常小的范围,波浪会显得越来越统一。为了波峰浪花,适当的设置Min,frec.在0.01和0.4之间,Max.frec不能超过1.0.接下来的图片显示了各种“Min.frec”效果,当然Max.freq是保持1.0,“Sample”2.0不变。


  Sample

  “Samples”值代表了生成修饰浪(modifier)数量。更高的数字代表有更多浪,导致很高扰乱的面。夸张的设置甚至能导致RealFlow崩溃。合理的值在10和40.值为50或更大,会产生更多随机,破坏掉波浪锐利的外观。



  图2.不同"Min.frec."值效果(0.05,0.10,0.30,0.75)。


  V scale

  "V"表示 “Vertical(垂直)”和“V scale(v 缩放)”直接决定了最大高度和波浪深度。默认,“V scale”设置是0.2,是十分好的值。可接受的设置在0.1和0.3之间。


  Angle(角度)

  最后这个参数决定了风方向

  用不同的值来试验,是很好的习惯,来达到不同的外观和形式。


  外观

  现在模拟出很好的波浪,但他们(运动)太快了。

  我们可以看到,波浪似乎是很快的混乱,但这不是自然的海洋面运动。要减慢波浪,另一个技术是需要:减慢运动(slow motion)。

  要模拟这个场景效果必须要很高的帧速率。播放栏执行普通的速度,例如帧速率30,25或24帧每秒。请打开“Simulation options”窗口调节fps值在125和175.最终帧速率大小取决于你场景缩放。对非常小的浪,帧速率可以在125-140之间,再大的浪至少要150fps.

  你在“Simulation”按钮下找到“Simulation options”窗口。你就点击那个小三角,窗口就会弹出,你就可以改变场景值了。请不要在RealFlow的“Preferences”窗口改变帧速率(fps rate),因为这是全局值,对所有工程都起作用。

  另一个不想要的效果是在模拟开始时,波浪面有负方向。不幸的是,这个效果不能忽视,所以请想一下偏移,当你添加场景工程时。



  图3:从本教程渲染出的图片


  用光滑材质的方法,尖锐的波浪会消失一点点。这在你最终渲染也会发生,尽管“Spectrum”修饰方便使用改变尖锐波浪。

  这surface具有所有RealWave特性,像泡沫贴图和顺流力(downstream force)

  图3显示的是场景渲染结果。灯光和材质有助于浪峰更好显示。材质用图片也能包含小的波纹,看起来更真实一点。请保持高的抗锯齿值,也会增加一点细节。


  图3的波浪设置是:

  Polygon size 0.03

  Weight 1.0

  Shape Sharp

  Min. frec. 0.1

  Max. frec. 1.0

  Samples 20

  V scale 0.2

  Angle 0.0


  一句话总结:想快速学效果没什么用,学习波浪本质很有用


Gerstner 波源代码:

  # -------------------------------------------------------------

  # Gerstner Waves

  # Based on the Gerstner Wave plugin by Next Limit Technologies

  # Python script for RealFlow 5+

  # Written by RF_toolfactory/Thomas Schlick, 2011

  #

  # Use this script at your own risk!

  #

  # Do not remove this copyright header.

  # -------------------------------------------------------------

  #--------------------------------------------------

  # Function: updateWave

  # This function is called by the simulation engine

  # when it is time to update the wave.

  # The parameter is the list of vertices that you have

  # to update and the initial positions of those vertices.

  # The vertex position represents the displacement respects

  # the initial positions.

  #--------------------------------------------------

  import math

  def updateWave( vertices, initPositions ):

  # These values can be animated or entered via a GUI

  dirWave = 30

  ampWave = 0.1

  lengthWave = 1.25

  speed = 0.1

  dirRadWave = (dirWave * math.pi) / 180.0

  dirVecWaveN = Vector.new(math.cos(dirRadWave), 0.0, math.sin(dirRadWave))

  dirVecWaveN.normalize()

  k_number = (2 * math.pi) / lengthWave

  k_waveVectorX = dirVecWaveN.getX() * k_number

  k_waveVectorY = dirVecWaveN.getY() * k_number

  k_waveVectorZ = dirVecWaveN.getZ() * k_number

  k_waveVector = Vector.new(k_waveVectorX, k_waveVectorY, k_waveVectorZ)

  angularVel = math.sqrt(9.81 * k_number)

  for i in range(0,len(vertices)):

  localVertexPos = initPositions[i]

  angle = (k_waveVector * localVertexPos) - (angularVel * scene.getCurrentTime() * speed)

  dispHorizontalX = -(dirVecWaveN.getX() * (ampWave * (math.sin(angle))))

  dispHorizontalY = -(dirVecWaveN.getY() * (ampWave * (math.sin(angle))))

  dispHorizontalZ = -(dirVecWaveN.getZ() * (ampWave * (math.sin(angle))))

  dispHorizontal = Vector.new(dispHorizontalX, dispHorizontalY, dispHorizontalZ)

  dispVerticalY = ampWave * (math.cos(angle))

  dispVertical = Vector.new(0, dispVerticalY, 0)

  vertices[i] = Vertex.new(localVertexPos + dispHorizontal + dispVertical)

  vertices[i].setVelocity(Vector.new(0.0, 0.0, 0.0))


把上面代码粘贴到TXT,然后后缀改成rfs格式,就能直接载入RealFlow了


,realflow案例,realflow教程