Emitters
Emitters器,顾名思义,发射流体粒子到场景中。它们类似于Unity的内置粒子发射器,但它们并不发射常规粒子。取而代之的是,它们发射的是Obi粒子,这些粒子可以相互作用,也可以与其他物体相互作用。
要创建一个发射器,GameObject->3DObject->Obi->Obi Emitter
默认情况下,所有的粒子都会从物体的原点发射。除了非常简单的效果外,还可以使用更复杂的形状作为发射粒子的源头。可以将任何一个ObiEmitterShape组件(正方形、圆盘、边缘、球体或图像)添加到场景中的任何对象中,并将ObiEmitter组件拖到其 "Emitter "属性上。这将允许发射器通过该特定形状发射粒子。
请注意,可以将一个发射器附加到多个形状上
ObiEmitters有很多参数,允许你指定如何和何时发射粒子:
Blueprint:对ObiEmitterBlueprint资产的引用。有两种类型的发射器蓝图:流体蓝图和颗粒蓝图。这决定了被发射流体的内部物理属性。更多信息请参见发射器蓝图。
Collision Material:用于解决碰撞的材料。
Phase:由该发射器发射的粒子相位。
Emission method:可以使用两种方式之一:
4-1. Stream:只要池子里有至少Min pool size的颗粒,就会不断发出颗粒。
4-2. Burst:每个发射器形状的分布点都将在一次爆炸中生成一个粒子。
Min pool size:在发射器开始发射之前必须准备好发射的粒子的最小数量(占蓝图容量的百分比)。
Speed:速度。设置为零时,发射将完全停止。数值越高,发射器将以该速度持续发射流体(单位为米/秒)。根据流体分辨率和发射器形状大小,自动计算出每秒发射的颗粒数量。这确保了尽可能平稳的发射。
Lifespan:从粒子的诞生到返回发射器粒子池之间的秒数。
Random velocity:应用于所有粒子的初始速度的随机方向的数量。设置为0将使粒子向其当前出生点指定的方向发射,而设置为1将使它们向完全随机的方向发射。
Use shape color:启用后,粒子会被它们所发射的形状的颜色所着色。
Emitter shapes
可以向场景中的任何对象添加发射器形状。一旦你给形状分配了一个发射器组件,发射器就会开始使用它来发射粒子。有一些标准的发射器形状,但如果需要的话,你也可以通过脚本创建自定义的形状。
Disk
Disk发射器使用在其XY平面上定义的圆来生成粒子:
Color:通过这个形状发射的粒子的整体颜色。
Radius:圆的半径,以局部为单位。
Edge emission:如果启用,粒子将从圆的边缘而不是内部发射。
Edge
Edge发射器从沿X轴定义的线段中产生粒子:
Color: 粒子在此形状下发出的整体颜色。
Lenght:边缘的长度,以局部单位表示。
Radial velocity:沿边缘长度扭转的速度量。
Sphere
Sphere发射器从球形体积中产生粒子:
Color:粒子在此形状下发出的整体色调。
Sampling method:可在基于网格的球体体积取样或常规的表面取样之间进行切换。
Radius:球体的半径,以局部为单位。
Density:控制使用的采样点数量。
Emitter blueprints
ObiEmitterBlueprints是定义发射器发射的流体的物理属性的资产,如粘度和密度。你可以为每个发射器只分配一个发射器蓝图,但你可以定义任意多的蓝图(水、烟雾、蜂蜜、血液、沙子等),并在运行时在它们之间切换。
所有流体的碰撞相关参数,如粘性或摩擦力,不是通过发射器蓝图来控制,而是通过ObiCollisionMaterials来控制
要创建一个ObiEmitterBlueprint,右键点击你项目的任何文件夹,然后选择Create->Obi->Fluid blueprint/Granular blueprint
Fluid blueprint
流体粒子之间将稳定密度约束,它将试图在每个粒子的附近保持一个恒定的密度。
Capacity:发射粒子的最大数量。发射器将生成一个包含这个数量的粒子池,新产生的粒子将被从粒子池中取出,而被破坏的粒子将回到粒子池中,以便以后重新使用。
Resolution :该参数控制用于代表 1 立方米(或 2D 中的平方米)流体体积的颗粒大小和数量。默认值(1)将使用每立方米1000个颗粒。较高的数值将导致颗粒的尺寸减小,因此每个体积单位将需要更多的颗粒。
Resolutions from left to right: 1,2.5,5
Rest density:流体密度,单位为kg/m3。该值用于计算当前分辨率下,每个粒子的质量。粒子质量与此值成正比,即高密度流体将由高质量粒子组成,低密度流体将由轻粒子组成。
Density ratios from left to right: 1:1,1:1.5,1:3
Smoothing:这设置了在寻找邻居以计算流体密度时考虑的每个粒子周围区域的半径。它是实际粒子半径的百分比。较大的值会产生更平滑的流体,但模拟成本也会更高。值为1(100%)将使粒子只考虑实际与它们接触的邻居。2 (200%)的值会将粒子流入的区域扩大到粒子本身的两倍。作为经验法则,这个值应该在1.5-3左右。
Smoothing radii from left to right: 1.2,2,3
Viscosity:粘度可以平滑流体颗粒运动时产生的速度场。高值会使流体看起来更厚,流动更慢,低值会使其看起来更轻。作为经验法则,该值应始终在0和1.5-2之间。
Viscosities from left to right: 0,0.1,1
Surface tension:增加该值将使流体尽量减少其表面积,导致形成球形水滴。低值会让流体表面呈现任何形状。将此值保持在0和1.5-2之间。
Surface tensions from left to right: 0,0.1,1
Buoyancy:控制流体与周围空气之间的相对密度。值为-1时,将使流体按重力指定的方向和速度加速(因为它使其密度大于空气)。值为 1 将使流体向相反方向加速(因为它比空气轻)。值为0将使流体无视重力。
Buoyancies from left to right: -1,-0.2,0.2
Atmospheric drag:空气阻力的大小。较高的大气阻力值(如50)将导致流体边界附近的颗粒移动较慢,可用于模拟烟雾和气体。
Drags from left to right: 0,20,50
大气层阻力必须大于零,流体才会受到力区(风)的影响。
Atmospheric pressure:空气对流体表面施加的内压量。高数值(如5)将使流体更紧凑。低值将使流体容易扩散。
Pressures from left to right: 0,8,-8
Vorticity:涡度限制量,它将有助于保持流体中的涡度细节。保持这个值相对较低(0-0.5)以获得最佳效果。高值会带来不稳定性。
Vorticities from left to right: 0,0.5,1
Diffusion:粒子之间的扩散数据被平滑化的速度。值越高,扩散速度越快。
Diffusion Data:有4个扩散通道可供选择。这些通道的含义完全由你决定:每个通道可以是温度、颜色、粘度或其他。这4个通道中包含的数据会随着时间的推移在颗粒之间被平滑化,速度由平均扩散特性决定。
Granular blueprint
颗粒材料是由表现得像刚性球体的颗粒组成的,这对沙子般的效果(巨石、碎片等)很有用。它们的分辨率和静止密度参数的行为方式与它们的流体对应物相同。
Randomness:颗粒大小的变化。这是由材料分辨率决定的超过基本粒度的百分比,因此20的值意味着颗粒将在其基本粒度的100%和120%之间。
Randomness from left to right: 0,15,30
Fluid rendering
Obi支持两种流体渲染技术:球形假体和屏幕空间溅射,分别由ObiParticleRenderer和ObiFluidRenderer实现
球形假体(ObiParticleRenderer)
屏幕空间溅射(ObiFluidRenderer)
Obi Particle Renderer
球形假体是一种特殊类型的正方形面片(面向摄像头的四边形),它看起来就像一个完美的光照,高度瓷砖化的3D球体,而成本却很低。ObiParticleRenderer组件可以使用这种技术将你的流体颗粒渲染成微小的球体。
要做到这一点,只需将该组件添加到任何actor中(例如一个ObiEmitter,但它也可以用于绘制布或绳索)。你还可以设置粒子的颜色,并在渲染它们时缩放使用的半径。
你可以提供任何你想用于粒子渲染的着色器,只要它遵循传递给顶点着色器的粒子数据。Obi包括内置渲染管道的粒子着色器,以及URP的着色器。你可以在Obi/Resources/ObiMaterials/URP中找到这些。
Obi Fluid Renderer
根据使用的可脚本化渲染管道,设置流体渲染的方式略有不同
Built-in:将ObiFluidRenderer组件添加到每个你需要能够渲染流体的摄像机中
Universal (URP):添加一个ObiFluidRendererFeature到你的管道的渲染器特征列表中
无论你使用哪种管道,都会看到一个类似的界面:
屏幕空间拼接涉及到使用ObiParticleRenderer生成的各个面片来绘制流体的平滑、连续的表示。所以,设置一个粒子渲染器是流体渲染的前提。为了使用流体渲染,你需要设置一个ObiParticleRenderer。然后将ObiFluidRenderer分配到ObiFluidRenderer的 "Particle Renderers "属性中。
渲染器界面的各个部分:
Basic blending:这控制了流体厚度缓冲区以及它与屏幕内容的混合方式。
1-1.Blend source/dest:控制流体与背景的混合方式。
1-1-a:Alpha blending (src=src alpha, dest=one minus src alpha)
1-1-b:Additive blending (src=one, dest=one)
1-2. Thickness Cutoff:这是一个流体厚度的阈值。低于此厚度的流体区域将被丢弃。
1-1-a:Low cutoff
1-1-b:High cutoff
1-3. Thickness Downsample:对厚度缓冲区进行降采样。增加它以使用较低分辨率的缓冲区。
Surface reconstruction:它控制流体表面的深度/法线生成。它是闪电/反射/折射所必需的
a. Surface reconstruction enabled
b. Surface reconstruction disabled
2-1. Blur radius:生成法线前应用的深度模糊程度。数值越高,表面越平滑
2-1-a:Low blur radius
2-1-b:High blur radius
2-2. Surface Downsample:对深度/正态缓冲区进行降采样。增加它以使用低分辨率缓冲区。
2-2-a:No downsampling
2-2-b:Downsampling = 4
Lighting:这是控制照明的
3-1. Smoothness:流体的表面光滑度。高值会导致小的镜面闪光,低值会导致表面看起来更粗糙
3-1-a:High smoothness
3-1-b:Low smoothness
Reflection :控制表面反射
4-1.Reflection:反射量
4-1-a:Low reflection
4-1-b:Chrome-like, high reflection
4-2. Metalness:控制反射金属度:高值会使反射/镜面与流体的表面颜色发生色差
4-2-a:High reflection, 0% metal
4-2-b:High reflection, 100% metal
Refraction:控制表面折射率
5-1. Transparency:流体透明度的大小:数值越高,越能让显示出背景。
5-1-a:Transparent fluid
5-1-b:Opaque fluid
5-2. Absorption:当光线穿过液体时,液体吸收了多少光线:数值越高,背景就会染上液体的颜色。这种效果在液体较厚的地方更为明显。
5-2-a:High absorption
5-2-b:No absorption
5-3. Refraction:光的折射量。这种效应在液体较厚的区域更为明显
5-3-a:Low refraction
5-3-b:High refraction
5-4. Refraction downsample:折射缓冲器的下采样。增加它以使用较低分辨率的缓冲器。
机制
有许多可能的方法来渲染流体。Obi使用的是屏幕空间的方法,不需要每一帧都程序化地生成一个网格,从而减少了CPU的工作量,充分利用GPU进行渲染。完整的渲染过程有5个步骤,每一帧都会发生。
从左到右:
首先,将当前屏幕内容存储在纹理缓冲区中,以备之后的折射。
所有的粒子都会将其深度渲染到屏幕外的深度缓冲区。
同时,它们的厚度和颜色也会渲染到厚度/颜色缓冲区。
步骤1中渲染的流体深度缓冲区用于生成法线缓冲区。
所有四个缓冲区都会合成到最终渲染中。流体深度缓冲区用于丢弃被场景中其他物体遮挡的流体碎片。
这类似于传统的延迟渲染器,有着相同的优缺点:渲染成本基本上与屏幕上的粒子数量无关,但这也意味着即使没有可见的粒子,也会有一个固定的成本与缓冲区生成相关。
内置的ObiFluidRenderer利用着色器变体为你使用的功能组合生成优化的着色器。例如:如果你正在渲染不透明的流体,没有折射,步骤#1将被跳过:根本不会渲染折射缓冲区,并且生成的着色器不会包括任何折射计算。
Mobile performance
对于桌面平台,你可以在大多数时间内使用全分辨率渲染和所有渲染器功能。然而,移动设备通常会受到更多的填充率限制,因此,如果可能的话,使用激进的下采样和跳过表面重建是有益的。使用简单的混合而不是折射也可以提高性能。
Particle advection
引用维基百科的话。“平流是指物质通过体积运动进行运输”。想象一下,一片叶子漂浮在河面上:河水流到哪里,叶子就到哪里。在这种情况下,叶子是被河水平移(搬运)的。
在Obi Fluid中,流体粒子可以用来贴近常规Unity粒子。由于常规粒子本身不执行任何昂贵的模拟(它们被动地被流体携带),你可以拥有比流体粒子更多的Unity粒子。这对于模拟泡沫、气泡、烟雾或为模拟添加有趣的内部细节是很有用的。
不过,如果advection粒子的数量非常大,或者你所针对的CPU的硬件线程很少,那么advection的成本还是很高的。
setup
要在 Unity 粒子系统上执行平移,只需向其添加一个 ParticleAdvector 组件即可。这个组件只需要一个对负责模拟流体的ObiSolver的引用。
一旦你把Shuriken Unity粒子系统设置成了平流,你需要确保它发出的粒子在空间上靠近流体粒子。如果没有,粒子就会坐在那里不动,因为它们不在流体流附近,因此不能被流体流携带。让我们看一个例子(包含在/Obi/SampleScenes文件夹中:FluidKarmanVortex.unity)
边缘型二维流体发射器
常规的Unity粒子系统,放置在流体发射器之上。这样粒子就会离流体足够近,让它贴近它们
机制
每一帧,对于每个Unity粒子,Obi都会确定所有比求解器的平流半径更接近它的流体粒子。然后它将粒子速度设置为所有邻近流体粒子的加权平均值。距离较近的流体粒子会获得更高的权重,因此它们比距离较远的粒子对最终的平流速度影响更大。
白色的球体是流体颗粒。红色的小点是常规的颗粒,正在被喷出的液体
Foam generation
Obi包括一个辅助组件,它将自动在满足一定条件的流体颗粒附近发射Unity颗粒。这使得模拟泡沫或气泡变得很容易。要使用它,只需在任何ObiEmitter中添加一个ObiFoamGenerator组件。
Emission rate:每秒钟可喷出的泡沫颗粒的最大数量。
Randomness:在流体粒子附近产生泡沫粒子时使用的抖动量。值为零时,将直接在流体粒子的顶部产生泡沫粒子。使用较小的值以获得逼真的外观。
Vorticity threshold:能使泡沫粒子发出的最小流体涡度。泡沫一般出现在颗粒具有高旋转运动的地方,因此可以使用该参数来控制泡沫出现所需的涡度。
Density threshold:能使泡沫颗粒喷出的最大流体密度。泡沫一般出现在流体表面附近,那里的密度较低。可以使用此参数来控制流体需要多轻才能出现泡沫。
Advector:ParticleAdvector用于喷射泡沫颗粒。