1-4期
195人加入学习
(33人评价)
Houdini 影视特效实验班

6个月零基础到入职

价格 ¥ 6198.00
教学计划
承诺服务

GroupExpresslon新节点

rand(@ptnum)> 0.5   这句话的意思是,把点重置成有0到1这个范围数,然后凡是大于0.5就选择

group_combine(暂且理解成集合吧)

 

length(@P)<5    矢量半径小于五就选择

[展开全文]

bbox 判定框

relbbox(节点入口;例如(0or1),范围;例如(@P))

v@Cd 顺着矢量方向走的颜色

set(bbox.x,bbox.y,bbox.z) 范围设置

[展开全文]

grouprange: 选区

group: edgeDepth Point 点延伸选区域

[展开全文]

我觉得这两节课只是一些扩展,在大体的形态上增加一些额外的小细节,只有一个地方需要注意的就是给白水粒子添加一个mass属性的时候,用到的属性是id属性,不能是@ptnum,因为白水粒子有消亡,而id属性能保证每个粒子的id属性值是不一样的

[展开全文]

其实这个pyro解算不需要输出density场,因为只用到了vel场,这样pyro的缓存大小更加小一些

[展开全文]

vop是把速度进行fit一下,输出一个属性,乘上ocean evaluation节点里面的置换vex语句,这样速度快的地方依然使用mesh本身的细节,速度小的地方就置换,产生更多的细节

[展开全文]

ocean source节点输出的四个场,分别是这样的,后续flip解算中,flip的volume limit会读取这个场;vel场是输出海洋表面的速度场,在flip模拟中同样引导水的动态;guidesink场是在flip模拟中,删除进入到这个场里面的粒子;guidingsurface场在flip模拟中引导场水的动态

 

 

Stick on Guide使流体粒子的速度和读取进来vel场的速度相匹配
Stick Scale流体粒子与读取进来的vel场的速度相匹配的量,1表示完全匹配,0表示完全不匹配
Max Distance在流体粒子多远的范围内应用Stick on Guide的最大世界空间距离
剩下的参数保持默认就好
Max Cells应用Stick on Guide时流体粒子像外推多少个vel场的体素,不如直接填距离,方便很多
Stick Bias在最大距离内达到流体粒子速度达到Stick on Guide设定的流体粒子速度的快慢
Normal Scale  Tangent Scale 在引导曲面上的法线方向和切线方向的速度调整量
 

[展开全文]

ocean source节点使用连接到第一个输入的ocean spectrum海洋波普节点来生成粒子和体积,这些粒子和体积可以用来驱动flip的解算,模拟出海洋的动态
这个节点可以只创建一层薄薄的粒子,这些粒子在flip中用来模拟海洋表面的运动;此节点还可以创建一个边界层,这个边界层可以可以形成一个缓冲区域,这样有助于flip模拟完成之后和整个洋面进行融合

Initialize 把ocean source节点的参数设置指定成某一个预设
   Wave Tank这个预设是生成一个满满的粒子池,但是因为启用了narrow band,看上去只有薄薄的一层粒子,这个预设对需要液体的完全模拟,比如海洋深处中物体与水的交互模拟最有用
   Guided Ocean Layer 这个预设是在海洋表面生成一个薄层粒子,这个预设对于模拟需要与海面做紧密匹配的液体最有用
   以上这两个预设,粒子的初始状态都受到了第一个输入接口ocean spectrum节点的影响,粒子出生的位置会匹配ocean spectrum节点生成的海洋波谱的位置以及具备海洋表面的速度等信息
   Flat Tank这个预设中的粒子第一个输入接口是没有的,所以flat tank预设下出生的粒子就只是平平的在水槽中,同样这个预设默认粒子塞满水槽的,但是因为启用了narrow band,看上去只有薄薄的一层粒子
Particle Separation粒子间距
Oversampling过采样,例如值2将创建两倍的粒子量
Grid Scale这个参数是用来决定体素的大小的(水是粒子和体积的一种混合计算,一般来说这个值为Particle Separation参数的两倍是万无一失的)
Size  Center水箱的大小和位置


particle标签栏,对输出的粒子进行控制
Create Particles在水箱中生成粒子,由ocean source节点的第一个输出口输出
Water Level水位,如果第一个输入口有接入ocean spect海洋波普节点,那么0表示水的最高位在海洋表面,如果第一个输入接口什么都没有,那么0表示水位在水平面上
fill volume,从水位开始,向水槽底部填充粒子,会把整个水槽填满
narrow band particle 启用窄带
Layer Size,当启用窄带的时候,这个值决定窄带有多深;当不启用窄带的时候,这个参数决定创建的粒子层有多深,当用做海洋模拟时,那么应该要深一些,如果浅了的话,那么如果海洋的上下浮动太大,太浅的粒子层在flip模拟中会让底露出来
Guiding Surface Thickness这个参数是只有当第一个输入接口有海洋波普节点的时候,并且ocean source节点还输出了guiding surface场的时候才有用,这个参数就是用来控制guiding surface场的厚度
Jitter Seed  Jitter Scale这两个参数就是对粒子进行抖动扰乱
Kill Inside Collision杀死位于第二个输入端内碰撞对象的所有粒子,输入对象必须是一个闭合的几何体,或者是一个体积

surface标签栏,surface标签栏,对输出的surface场进行控制
depth  对surface场进行偏移输出,这与简单地偏移输出Surface场不同,因为它考虑了深度衰减设置
smoothing 对surface场进行一个平滑

smoothing 对surface场进行一个平滑

Velocity标签栏(这一栏全部保持默认)
velocity field是否输出一个具备海洋速度的速度场
Max Extrap Cells生成速度场的值的时候每个粒子向外推多少个体素以生成速度值

Boundary Layer(对创建的边界层的控制)
是否创建边界层,以及控制边界的大小

Surface Evaluation对ocean source生成的粒子形态控制
粒子的ocean形态由第一个输入端的ocean spectrum节点来决定
time(保持默认就好)如果不保持默认,粒子的形态不会随着ocean spectrum节点生成的海洋波普运动而运动,只会保持第一帧的形态
Downsample 下采样,对ocean spectrum节点生成的海洋波谱进行下采样,比如原来的分辨率是10,也就是2的十次方,这个参数为2的话,那么进来的海洋波普的分辨率是8,也就是2的八次方
Max Resolution 直接指定进来的海洋波普的分辨率是多少,比上面的下采样方便多了
Depth Falloff 粒子位于海面之下的变形和速度如何下降
  None不会有变化
  Exponential所有值在海洋表面下都具有相同的指数衰减
  Exponential by Frequency按海洋波谱的频率缩放进行指数衰减,这是最准确的,相比前两个耗时也更长
Falloff Scale衰减的缩放,当depth falloff模式选择为Exponential by Frequency选项时,就设置为1
Depth Divisions深度轴上的划分数,只有当depth falloff有变化的时候,这个参数才有意义
上面这三个参数,保持默认就好
Max Displacement Frame 当ocean source节点读取了第一个输入端ocean spectrum节点的海洋波普,就是这个参数去使粒子去到海洋表面的位置,值为1则代表每一帧计算一次,一般来说每帧计算一次就能得到一个比较正确的结果,如果海洋波普运动过快可试着提高此参数来使粒子匹配到海洋表面

粒子的flat形态就是一个平平的水槽形态
Scatter Density    其实就是撒点,在已有粒子内再增加一些粒子,值为1的时候会为水的表面创建一个平坦的表面,再增加这个值其实就是过采样了,会增加粒子的数量
Oversampling Bandwidth如果启用了oversampling参数,那么这个参数才能有意义,这个参数是控制oversampling产生的粒子分布在哪里水的表面哪个部分,这个参数乘以particle separation参数得到的值就是新增粒子距离水表面分布的地方,并且这个参数开启有值,那么oversampling参数才会增加粒子数量,不然oversampling参数开了也是白开
综上所述,这两个参数保持默认就好
 

[展开全文]

在VOP里面的操作,我觉得compare判断节点后面接two way switch节点会不会比较好一点,毕竟这是一个官方给的组合,理解上也会方便一点,满足条件输出imput1,不满足条件输出input2.

 

 

这些VOP连线可以用vex代码直接来写,这是我写出来的,经过测试和VOP连线是一样的

v@Cd = set(0,0,0);
float sample = volumesample(1, 0, v@P);
vector gradient = volumegradient(1, 0, v@P);
vector particle_for_surface_dir = gradient * sample * -1;
if(sample < 0.1){
    i@in_water = 1;
    v@Cd.x = 1;
    v@P = particle_for_surface_dir + v@P;
    v@v *= 0.7;
    f@life *= 0.7;
}  else {
    i@in_water = 0;
    v@Cd.y = 1; 
}

[展开全文]

之前有个SDF,可以直接拿过来用

[展开全文]

这两节课讲的是模型跟随一个面的运动,我更偏向于直接使用matrix矩阵来做,不想使用channel通道来做,因为我对三维的通道概念还没理解到底是个什么

这是我的节点图

 

接下来是每一个wrangle节点里面的vex代码,我不做解释了,因为要从矩阵的概念开始讲,太长了,帮助文档上会有详细的讲解

 

第一个wrangle     v@center = getbbox_center(0);

第二个wrangle   

int goalprim;
vector goaluv;
xyzdist(1, v@center, goalprim, goaluv);

i@goalprim = goalprim;
v@goaluv = goaluv;

第三个wrangle

v@goalN = primuv(1, "N", i@goalprim, v@goaluv); 
v@goalP = primuv(1, "P", i@goalprim, v@goaluv); 

vector prim_center_uv = set(0.5, 0.5, 0);
vector prim_offset_uv = set(0.51, 0.5, 0);
vector prim_center_P = primuv(1, "P", i@goalprim, prim_center_uv);
vector prim_offset_P = primuv(1, "P", i@goalprim, prim_offset_uv);

v@tangent_U = prim_offset_P - prim_center_P;
v@tangent_U = normalize(v@tangent_U);
v@goalN = normalize(v@goalN);

v@tangent_V = cross(v@goalN, v@tangent_U);

v@tangent_U = -cross(v@goalN, v@tangent_V);

第四个wrangle 

4@m = set(v@tangent_U.x, v@tangent_U.y, v@tangent_U.z, 0,
          v@tangent_V.x, v@tangent_V.y, v@tangent_V.z, 0,
          v@goalN.x,     v@goalN.y,     v@goalN.z,     0,
          v@goalP.x,     v@goalP.y,     v@goalP.z,     1);
          

4@m = invert(4@m);

 

第五个wrangle v@P = v@P * 4@m;

 

第六个wrangle 

v@goalN = primuv(1, "N", i@goalprim, v@goaluv); 
v@goalP = primuv(1, "P", i@goalprim, v@goaluv); 

vector prim_center_uv = set(0.5, 0.5, 0);
vector prim_offset_uv = set(0.51, 0.5, 0);
vector prim_center_P = primuv(1, "P", i@goalprim, prim_center_uv);
vector prim_offset_P = primuv(1, "P", i@goalprim, prim_offset_uv);

v@tangent_U = prim_offset_P - prim_center_P;
v@tangent_U = normalize(v@tangent_U);
v@goalN = normalize(v@goalN);

v@tangent_V = cross(v@goalN, v@tangent_U);

v@tangent_U = -cross(v@goalN, v@tangent_V);
 

第七个wrangle  

4@m = set(v@tangent_U.x, v@tangent_U.y, v@tangent_U.z, 0,
          v@tangent_V.x, v@tangent_V.y, v@tangent_V.z, 0,
          v@goalN.x,     v@goalN.y,     v@goalN.z,     0,
          v@goalP.x,     v@goalP.y,     v@goalP.z,     1);
          

第八个wrangle  v@P = v@P * 4@m;

 

这样就可以让船跟随洋面运动

[展开全文]

这个POPvop是从ocean foam节点里面复制过来的,关于这几个自定义的参数解释在官方文档上有详细的解释,作用是使密度好的地方粒子持续的时间更长,密度低的地方粒子持续的时间更短

 

上面这几节课全部都是关于白水粒子生成和动态的原理性讲解,不仅仅可以在海洋上使用,也可以在flip的解算中使用,只要有vel场,surface场就行,vel场使粒子跟随水面的运动,surface场使粒子紧紧的依附在水的表面

[展开全文]

其实streak和cell两个force都是一个排斥力,一模一样的设置,只是排斥力的大小不一样而已,这两个力的大小由mass这个属性值来决定,上面的streak因为mass属性值小,往外排斥的力小,看上去有条纹,下面的cell因为mass属性值大,往外排斥的力大,能清晰的看到蜂窝状

 

这两个设置里面唯一的区别就是pcfind radius节点的radius scale参数不同,这个决定目标点对周边多大范围的粒子产生条纹或者产生蜂窝

popsource节点发射的目标粒子决定有多少条纹和多少蜂窝

 

 

[展开全文]

pcfind radius节点会考虑被查找点的radius channel,如果搜索半径和被查找点的radius channel有交集,那么这个被查找点也会被找到;pcfind radius节点最终输出是一个数组,这个数组里面是被查找到的点的点序号
input和filename参数都是用来确定查找的对象,一个是通过连线,一个是直接写路径
point group搜索对象如果有点组,那么填写这个组名,PCfind radius节点只会在这个组里面进行查找;也可以直接输入0-10(只在0到10号的组里面进行查找),也可以填写@Cd.x<0.5这样的表达式
position channel 当要查找一个点的时候当然是通过查找这个点的位置,从而找到这个点,这个参数就是被查找点的位置(这么说不知道有没有说清楚)(保持默认就好)
radius channel 拿哪一个属性作为被查找点的半径,默认是pscale属性(保持默认就好),如果这一空不填,pcfind radius节点等效于pcfind节点
radius scale 被查找点的半径的缩放(这两个radius参数都是针对被查找点的)
location  search radius  max point这三个参数和其他所有pointcloud节点一样,不做解释了

 

for each循环是对数组进行操作,每一次循环是对数组里的单个元素进行操作,在这里就是对上个节点输出的被查找到的点的序号数组中每个单独的点序号进行操作,即是对被查找到的每一个点进行操作


Get Attribute可以从硬盘上存储的几何体或者从外部的几何体中获取属性值
signature 要获取什么类型的属性数据
input  geometry file参数都是从外部读取文件获取属性值,一个是通过连线,一个是直接写路径
Attribute Class属性存储在点,顶点,面和detail上面,这个参数说指定在哪个里面进行属性的获取
Attribute 要获取的属性的名称
Point or Primitive点序号或者面序号 当Attribute Class为point种类的时候,读取连接进来的几何体上的哪个点序号的属性值    
Vertex 这个顶点还不知道是怎么回事
Default Value如果获取不到这个属性,则使用这个默认值
 

[展开全文]

POP Advect by Volumes节点的作用是通过读取一个vel场生成一个力来驱使粒子运动(所以如果在flip模拟中,这个节点应该是添加在particle velocity接口上),通常读取vel场是从硬盘中读取,但是这个节点可以从现有的模拟中读取vel场,在velocity source选项中选择DOP data,在DOP date参数中选择现有的DOP模拟中的object物体,field参数中填写vel,就能够读取现有模拟中的速度场

velocity scale参数,对读取进来的速度场的缩放比例

Advection Type几种不同的对流类型
update force通过读取进来的vel场计算出一个力,这个力去影响粒粒子的加速度,类似于pop force节点
Treat as Wind通过读取进来的vel场计算出一个力,把这个力视作与粒子匹配的风速,这就会把粒子直接拖到目标速度(保持默认的勾选就行)
Force Scale读取进来的vel场计算出来的力直接应用在粒子上,这个参数就是对这个力的缩放(我不知道哪种情况下要使用这样的力)
Air Resistance空气阻力,对粒子的影响有多强(保持默认1就行,能使粒子迅速的匹配到风力)
remap force对力的一个重映射(我还没有弄明白这个reap贴图的横轴纵轴分别代表什么,但是并不重要,因为之所以要使用这个节点当然是希望粒子能够跟随导入进来的vel场运动,再去修改这个力让粒子产生别的运动不如直接回去修改速度场)

update velocity粒子本身有速度的话,粒子的速度会和读取进来的速度场进行混合,使粒子速度快速匹配上读取进来的速度场(这种方式比较耗资源,而且一般来说使用这个节点的情况下,粒子本身是没有速度的)
Velocity Blend每一步幅下粒子的速度要混入vel场的速度的量

update postion这个是直接移动粒子位置,其原理还不是很明白

Ignore Mass忽略质量

Advection Method对粒子进行对流运动的方法,默认的single step单步法速度很快,在一个体素上只读取一次,剩下的集中追踪法更加准确,会在一个体素上多读取几次,相应的也会增加解算时间

 

volume gradient函数,计算出一个体积的梯度,梯度是一个向量,方向指向是体积内volume值呈现增长的方向;梯度向量的大小,因为体积分为两种,常见的field和SDF,梯度向量的大小在两种体积中稍有不同,在field中,梯度向量的大小是随机的;在SDF中,volume值越接近0的地方,梯度向量的大小越接近1。
在field中,如果超出了primtive number的范围,或者volume值达到了这个体积设定的最大值,那么不会有梯度向量;在SDF中,如果volume值达到了这个体积设定的最大最小值,那么不会有梯度向量

这是一个SDF,粒子都生成在这个SDF的表面,所以volume gradient生成的梯度向量的大小无限接近于1,方向指向是垂直于SDF的表面的;
这是一个SDF,粒子都生成在这个SDF的表面,所以volume sample求出的当前粒子的volume值非常小,无限接近于0;
以上两个数值相乘以,得到一个方向垂直于SDF表面,大小不大的矢量,拿P矢量减去这个矢量,给到P,那么粒子的位置就会改变一些,从而得以附着在SDF的表面上

[展开全文]

ocean foam节点,接口端接海洋波谱节点,作用是创建海洋表面的泡沫粒子

emitter模式,粒子是根据发射条件在指定的范围内创建,这些粒子可以被送到任何用于发射的自定义粒子模拟中
solver模式,把emitter模式下发射出来的粒子进行模拟,这个模式下的粒子输出可以直接用作ocean surface材质球的泡沫渲染
emitter模式只是单纯的创建粒子,solver模式会对emitter模式下创建出来的粒子进行模拟

Particle Density每单位面积要发射的粒子密度,值越高粒子越多
region参数栏都是一些显而易见的参数,不多做解释了,只有一个Z density falloff,表示沿Z轴距离摄像机较远的区域讲发射较少的粒子,这样可以节省资源,数值为0的时候,与摄像机的距离不管是多少都不会影响粒子的密度
condition条件参数部分
min cusp最小尖点,在海浪高于这个尖点的地方发射泡沫粒子
min velocity最小速度,在海浪移动速度超过这个速度的地方发射泡沫粒子
min height最小高度,在海浪高于这个高度的地方发射泡沫粒子

ocean evaluation海洋估计参数部分
time和downsample两个参数解释起来比较麻烦,也没什么用,保持默认就行
displacement particle置换粒子,泡沫粒子被创建出来之后是在一个平面上,该参数启用之后,泡沫粒子会被置换在海浪上,当想要自定义模拟泡沫粒子时开启这个选项

solve模式
foam参数部分
life expectancy泡沫粒子的寿命,单位秒
life variance泡沫粒子的寿命变化率
drift rate漂移速率,赋予泡沫粒子水平海洋速度的量,增加该值,会增加曲面上泡沫的挤压和拉伸
preserve foam根据泡沫粒子的局部密度增加或减少泡沫粒子的寿命,这样有助于形成团块和条纹状的泡沫
min foam density当泡沫粒子周围的粒子密度低于这个值的时候,会按reduction rate减少率参数设定的值每一步按比例减少其寿命
max foam density当泡沫粒子周围的粒子密度从min foam density参数设定的值达到这个值的范围的时候,会按preservation rate保存率参数设定的值每一步按比例增加其寿命
preservation rate增加具有足够高的局部密度的泡沫粒子寿命比例,该参数表示每秒要添加的寿命的秒数,因此,如果该参数大于1,那么高密度泡沫粒子块就很难被杀死
reduction rate 减少率,减少低的局部密度的泡沫粒子寿命比例,该参数表示每秒要减少的寿命的秒数
keep attribute保留泡沫粒子模拟中产生的属性,这些属性可作用在材质球上,这样才能得到正确的效果(保持他的默认)

simlution参数部分,和其他所有simulation参数是一样的,不做解释了
 

 

ocean foam节点如果只是用来发射泡沫粒子,那么这些泡沫粒子的寿命只有发射出来的这一帧,方便拿来做泡沫粒子自定义模拟的源

[展开全文]

流程是这样的,输出ocean spectrum节点生成的海洋波谱文件,作为ocean surface材质球的置换文件,把ocean surface材质球赋给一个几何体(通常就是一个面片),用来渲染海洋
Ocean Evaluate节点只是用来预览ocean spectrum节点生成的波谱文件

 

 

ocean spectrum节点:生成包含用于模拟海浪的信息的体积,这些信息模拟了随时间推移恒定风和潮汐力对海浪的影响
这些信息是三个场,
phase场,代表每个波的相位偏移
frequency场,代表每个波的角频率
amplitude场,代表每个波的振幅

resolution exponent 生成的三个场的体素分辨率,最终的分辨率都是2的该参数值的次方,例如该参数值为9时,体素分辨率为512*512
Grid Size 生成的海洋波谱的世界空间大小
Grid Center 生成的海洋波谱的世界空间中心
deepth 海洋的深度,深海中的波具有很强的色散关系,大的低频波比小的波移动得快,减小此参数可减少色散量,使波速更加均匀(保持默认就行)
gravity 重力(保持默认就行)
seed 海洋波普的相位偏移和随机分布的种子值
Time Offset 对海洋波谱进行模拟预览时加上的时间上的偏移量,单位是秒
Time Scale 海洋波普运动的剧烈程度
Loop Over Time 启用时,海浪将在时间段指定的时间内循环,单位是秒,过短的时间周期波的运动会产生一个自适配的慢运动,比如只有一秒钟的循环周期,那么波的运动就会自适配成一个缓慢的,很难看出单一循环的运动
Loop Period 循环周期的时间长度,单位是秒


wind 选项卡
direction 风的方向,0是X轴,值为正,风的方向做顺时针偏转,值为负,风的方向做逆时针偏转
Speed 风速,更高的风速会产生更大的低频波,通常会增加海洋光谱的动态范围,值越大,有点类似把波峰更加抬高,把波谷更加压低,这就形成了更大的低频波
Directional Bias 定向偏压,波浪将与风向对齐的量,与风向不一致的波浪将被抑制
Directional Movement 定向运动,波浪与风同向移动的量。当该值较低时,海洋将包含与风对齐但与风相反方向移动的波浪。增加该值将抑制这些波,只留下朝同一方向移动的波
Chop 使波峰更加的尖锐,将该值增加得太高会导致波浪变得过于尖锐并在其自身上发生反转(保持默认就行)

Amplitude 选项卡
Normalize 海洋波谱是通过降低不需要的方向传播的波的振幅来形成的,这会导致海洋的整体高度随着波浪的形状而改变,启用此参数时,会使海洋保持一致的波高,影响波高的参数就只有wind选项卡下面的speed参数和amplitude选项卡下面的scale参数了(保持默认就行)
Reference Wind 启用Normalize参数后,波浪的高度对风的参考,只有当场景中的单位发生变化的时候才要改动
Scale 缩放所有波的振幅强度(其实就是对波浪高度的缩放)
Random Distribution 这是一个post参数,当对波的参数已经应用成形之后,对波幅的缩放再做一个随机的分布,有好几种不同的随机方式,默认的高斯随机往往是最符合海洋波谱的实验模型(保持默认就行)
Min Wavelength 抑制波长小于此值的任何波,这有助于在非常高的分辨率下消除非常小的波的混叠,个人经验在分辨率为12以下的情况下保持默认为零就行,不然会丢失很多细节
Filter Above Resolution    抑制海洋波谱中存在的高于这个分辨率的波,例如该参数设置为8,则此波谱的频率将只会低于分辨率为8的波谱
Filter Below Resolution 抑制海洋波谱中存在的低于这个分辨率的波,例如该参数设置为0,则此波谱的频率将只包含分辨率高于0的波谱
当要进行波谱分层或者对最高频率应用mask或者noise的时候,这两个参数可同时使用
Remap Amplitude    勾选之后可使用一张渐变贴图来修改波的振幅的分辨率(这个重映射我觉得没什么用,不知道应该在哪种情况下使用)
Max Remap Resolution 下面渐变贴图的竖轴的变量
Amplitude Ramp 渐变贴图,左侧代表低频,右侧代表高频

 


Wave Instancing和mask这是波浪实例和波浪的mask,我还不知道是什么个原理,希望有知道的人能多交流交流

[展开全文]

在点的运动轨迹上进行点的插补,使用trail节点就行,配合point replicate节点效果更好一点,另外把点的速度进行一下随机化,也可以在一定程度上填补烟雾的空隙

[展开全文]

做碎块的烟雾我还是喜欢用经典方法来做,更方便控制

[展开全文]

pyro中烟雾火焰等上升的速度还是由浮力来决定,速度场不是不用,只是不需要开到1那么大,有一半的速度场的应用就已经是很大的值了,在这里限制速度场的大小也是这个原因,不过这样的写法其实并不标准,应该先拆分速度场的大小和方向,再限制速度场的大小,然后乘回速度场的方向,这样写比较接标准
float vel_len = length(v@vel);
vector vel_normal = normalize(v@vel);
vel_len = clamp(vel_len, -50, 50);
v@vel = vel_len * vel_normal;

[展开全文]