那么,如何在不进行高开销光线-模型交点计算的前提下,让粒子“命中”模型?这里需要用到一个名为ParticleModelShape3D的类型,它可以按照指定模型的轮廓发射粒子,并通过在发射器中设置速度,将其发射到特定方向 。只要将速度方向朝向天空,并令粒子系统时间倒流,就会产生粒子从上方落下、撞击模型的视觉效果。

使用零速度轨迹发射器(Trail Emitter)实现雪花积累效果。
ParticleEmitter3D.reversed属性
若将整个系统时序倒转运行,则会给同一系统中添加其他粒子效果带来不便 。为此,我们在发射器上新增了reversed属性,允许仅对该发射器启用时序倒转,而其他粒子发射器仍按照正常时间顺序运行。
以下示例展示了如何使用线条粒子(Line Particles)、模型形状(Model Shape)与轨迹发射器(Trail Emitter)来实现雨滴及溅水效果。
// Rain particleLineParticle3D {id: rainParticle...}Component {id: modelComponentModel {// The mesh containing only the top parts of the spheresource: "meshes/sphere_top.mesh"}}// Rain particle emitterParticleEmitter3D {id: emitterparticle: rainParticlereversed: trueshape: ParticleModelShape3D {model: modelComponentfill: false}velocity: VectorDirection3D {direction: Qt.vector3d(0, 800, 0)directionVariation: Qt.vector3d(2, 0, 2)}}// Splash particleSpriteParticle3D {id: splashParticle...}// Splash particle trail emitter following the rain particleTrailEmitter3D {follow: rainParticleDynamicBurst3D {id: splashBurstamount: 20amountVariation: 2triggerMode: DynamicBurst3D.TriggerEnd}emitBursts: splashBurstparticle: splashParticlevelocity: VectorDirection3D {direction: Qt.vector3d(0, 0, 10)directionVariation: Qt.vector3d(50, 50, 1)}}
现在我们可以实现雨水击中模型并向特定方向溅起水花的效果。但如果溅水能随模型表面形状自适应——即粒子以特定角度击中曲面时,沿反射角度溅出——效果会更理想。
ParticleEmitter3D.EmitMode
发射器的发射模式(EmitMode)支持更精细的粒子方向控制。在默认模式之外,新增了两种基于模型形状的方向控制模式。
ParticleEmitter3D.SurfaceNormal:将发射方向改为遵循表面法线。当发射速度朝向Z轴时,粒子将沿表面法线方向发射。
ParticleEmitter3D.SurfaceReflected:用于轨迹发射器,发射方向为根据表面法线与被跟随粒子速度计算所得的反射向量

Default与SurfaceNormal发射模式在Suzanne网格上的对比效果。
将轨迹发射器的发射模式设置为ParticleEmitter3D.SurfaceReflected,溅水粒子即可从模型表面产生反射效果。
TrailEmitter3D {...emitMode: ParticleEmitter3D.SurfaceReflected}

粒子在球体表面使用SurfaceReflected模式弹射的效果演示。
至此,我们已具备针对单个模型实现雨滴效果的基本构件。但如何将其扩展到包含多个模型的应用场景?若为每个模型单独添加雨滴效果,会带来副作用:各模型拥有各自的雨滴密度,导致场景雨势不均匀;此外,雨水还会穿透彼此重叠的模型 —— 例如,当模型位于地面上方时,地面仍会在模型正下方产生雨滴。为解决上述问题,可以提前计算整个场景的网格,但这样得到的是静态网格,导致模型无法在场景中移动 。
ParticleSceneShape3D
场景形状(Scene Shape) 可以根据场景中的模型,动态计算整个场景的形状。 该形状以一张覆盖在场景上方的网格来表示,网格的每个顶点对应其下方所有模型多边形的最高点。当相邻顶点之间高度差过大,或网格顶点下方不存在模型多边形时,将在网格中创建孔洞。
当场景中的模型发生移动时,形状会自动重新计算,因此也适用于动态场景。开发者可以设置网格分辨率、网格范围(决定形状大小)、中心位置,以及指定需要从计算中排除的节点。此外,还可以通过属性获取几何数据,例如用于调试目的。
ParticleEmitter3D {id: emittershape: ParticleSceneShape3D {id: sceneShapescene: sceneRootsceneCenter: Qt.vector3d(0, 0, 0)sceneExtents: Qt.vector3d(1000, 500, 1000)excludedNodes: [debugNode]shapeResolution: 50}}Model {id: debugNodegeometry: sceneShape.geometry}

雨滴效果在汽车配置器演示项目中的应用
汽车配置器演示项目已随Qt 6.11加入雨滴效果,并同步附带了雪花效果。
来源:IFD优飞迪