
歧视性重力的困境
您描述的问题在使用 Maya 的每个粒子属性时很常见。您试图单独控制每个粒子,但当前的表达式同时影响所有粒子,因为您修改的是全局力场,而不是每个粒子的特定属性。
关键在于理解 GravityField1.magnitude 是一个影响连接到该场的的所有粒子的全局属性。您需要一种方法,让每个粒子单独决定如何响应重力,而不是改变重力本身。
在粒子表达式中,改变全局场就像为特定一个人修改地球重力
使用自定义动态属性的解决方案
正确的方法是为每个粒子添加一个自定义动态属性,来决定它是否受重力影响。这个属性是按粒子评估的,而不是全局的。
- 添加自定义属性:在粒子形状中,Attributes > Add Attributes
- 创建 affectGravity:名为 affectGravity 的每个粒子浮点属性
- 配置为动态:确保它是粒子属性,而不是对象属性
- 值 1 或 0:1 表示受重力影响,0 表示免疫
正确配置表达式
您的创建表达式正确分配了随机索引,但运行时表达式需要完全重写。您必须使用自定义属性,而不是修改全局场。
您当前代码的问题是,每个通过表达式的粒子都会修改 GravityField1.magnitude,从而影响所有其他粒子,造成您描述的持续变化效果 😅
- 创建表达式:particlesShape1.affectGravity = rand(0,1) > 0.5 ? 1 : 0
- 动态后运行时:每个粒子的单独控制
- 使用条件运算符:? : 用于干净的二元决策
- 保留 indexp 用于实例:但将重力逻辑分开
与重力场的连接
一旦每个粒子都有 affectGravity 属性,您需要将此属性连接到重力场的影响。Maya 通过连接编辑器或额外表达式允许这样做。
您可以使用 affectGravity 属性来调制重力对每个单独粒子的作用力,而不影响其他粒子。
- 使用 ramp 的选项:将 affectGravity 连接到场的影響坡道
- 使用表达式的选项:particlesShape1.worldVelocity += gravity * affectGravity
- 使用 particle sampler 的选项:用于着色器中的更高级控制
- 使用 goal weights 的选项:使用该属性作为乘数
逐步更正代码
这里是完整且更正的实现。请严格按照此顺序操作,以避免您遇到的问题。
首先删除您当前的表达式,从零开始创建。有时损坏的表达式会导致不可预测的行为。
- 步骤 1:添加每个粒子的动态属性 affectGravity
- 步骤 2:创建表达式:particlesShape1.affectGravity = (rand(0,1) > 0.5) ? 1 : 0
- 步骤 3:动态后运行时:particlesShape1.velocity += <<0,-9.8 * affectGravity,0>>
- 步骤 4:单独保留您的 indexp 表达式用于实例
优化以获得更好性能
动态后运行时表达式在计算上可能很昂贵,尤其是涉及数千粒子时。对于复杂系统,请考虑更高效的替代方案。
粒子目标或自定义场在某些情况下可以提供相同的控制并具有更好的性能。请实验以找到适合您场景的理想平衡。
- 使用目标代替表达式进行简单运动
- 考虑 nParticles 用于更复杂的模拟
- 使用 MASH 测试带有条件逻辑的实例
- 评估 Bifrost 用于高级粒子系统
无表达式的替代解决方案
如果表达式仍给您带来问题,可以使用两个独立粒子系统的方法。这不太优雅,但更稳定。
创建一个用于有重力的对象发射器,另一个用于无重力的对象,然后在渲染中组合结果。这完全避免了运行时表达式的需求。
- 系统 A:具有正常重力的粒子
- 系统 B:无力场的粒子
- 在两个系统之间随机化发射
- 在合成或渲染层中组合
实施这些解决方案后,您的粒子终于会独立决定是否受重力影响……尽管有些可能会叛逆地选择在太空中漂浮,而其他则服从物理定律 🌌