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了