Skip to main content

使用 Quick3D Particles 实现雨滴效果

评论

以下是 Quick3D.Particles 模块在 Qt 6.10 和 6.11 中新增功能的概述。本次更新的目标是支持与场景产生视觉交互效果的粒子特效,同时避免引入高开销的模拟计算。本文将以雨滴效果为例,逐步介绍各项新特性。

雨滴效果由两部分构成:粒子撞击场景模型上的过程,以及撞击后触发的飞溅粒子效果。

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

reversedSnow

使用零速度轨迹发射器(Trail Emitter)实现雪花积累效果。

ParticleEmitter3D.reversed 属性

若将整个系统时序倒转运行,则会给同一系统中添加其他粒子效果带来不便 。为此,我们在发射器上新增了 reversed 属性,允许仅对该发射器启用时序倒转,而其他粒子发射器仍按照正常时间顺序运行。

以下示例展示了如何使用线条粒子(Line Particles)、模型形状(Model Shape)与轨迹发射器(Trail Emitter)来实现雨滴及溅水效果。


// Rain particle
LineParticle3D {
    id: rainParticle
    ...
}

Component {
    id: modelComponent
    Model {
        // The mesh containing only the top parts of the sphere
        source: "meshes/sphere_top.mesh"
    }
}

// Rain particle emitter
ParticleEmitter3D {
    id: emitter
    particle: rainParticle
    reversed: true
    shape: ParticleModelShape3D {
        model: modelComponent
        fill: false
    }
    velocity: VectorDirection3D {
        direction: Qt.vector3d(0, 800, 0)
        directionVariation: Qt.vector3d(2, 0, 2)
    }
}

// Splash particle
SpriteParticle3D {
    id: splashParticle
    ...
}

// Splash particle trail emitter following the rain particle
TrailEmitter3D {
    follow: rainParticle
    DynamicBurst3D {
        id: splashBurst
        amount: 20
        amountVariation: 2
        triggerMode: DynamicBurst3D.TriggerEnd
    }
    emitBursts: splashBurst
    particle: splashParticle
    velocity: VectorDirection3D {
        direction: Qt.vector3d(0, 0, 10)
        directionVariation: Qt.vector3d(50, 50, 1)
    }
}

现在我们可以实现雨水击中模型并向特定方向溅起水花的效果。但如果溅水能随模型表面形状自适应——即粒子以特定角度击中曲面时,沿反射角度溅出——效果会更理想。

ParticleEmitter3D.EmitMode

发射器的发射模式(EmitMode)支持更精细的粒子方向控制。在默认模式之外,新增了两种基于模型形状的方向控制模式。

ParticleEmitter3D.SurfaceNormal :将发射方向改为遵循表面法线。当发射速度朝向 Z 轴时,粒子将沿表面法线方向发射。

ParticleEmitter3D.SurfaceReflected:用于轨迹发射器,发射方向为根据表面法线与被跟随粒子速度计算所得的反射向量

emitModes

Default 与 SurfaceNormal 发射模式在 Suzanne 网格上的对比效果。

将轨迹发射器的发射模式设置为 ParticleEmitter3D.SurfaceReflected ,溅水粒子即可从模型表面产生反射效果。


TrailEmitter3D {
    ...
    emitMode: ParticleEmitter3D.SurfaceReflected
}

reflectedParticles

粒子在球体表面使用 SurfaceReflected 模式弹射的效果演示。

至此,我们已具备针对单个模型实现雨滴效果的基本构件。但如何将其扩展到包含多个模型的应用场景?若为每个模型单独添加雨滴效果,会带来副作用:各模型拥有各自的雨滴密度,导致场景雨势不均匀;此外,雨水还会穿透彼此重叠的模型 —— 例如,当模型位于地面上方时,地面仍会在模型正下方产生雨滴。为解决上述问题,可以提前计算整个场景的网格,但这样得到的是静态网格,导致模型无法在场景中移动 。

ParticleSceneShape3D

场景形状(Scene Shape) 可以根据场景中的模型,动态计算整个场景的形状。
该形状以一张覆盖在场景上方的网格来表示,网格的每个顶点对应其下方所有模型多边形的最高点。当相邻顶点之间高度差过大,或网格顶点下方不存在模型多边形时,将在网格中创建孔洞。
当场景中的模型发生移动时,形状会自动重新计算,因此也适用于动态场景。开发者可以设置网格分辨率、网格范围(决定形状大小)、中心位置,以及指定需要从计算中排除的节点。此外,还可以通过属性获取几何数据,例如用于调试目的。

ParticleEmitter3D {
        id: emitter
        shape: ParticleSceneShape3D {
            id: sceneShape
            scene: sceneRoot
            sceneCenter: Qt.vector3d(0, 0, 0)
            sceneExtents: Qt.vector3d(1000, 500, 1000)
            excludedNodes: [debugNode]
            shapeResolution: 50
        }
    }

    Model {
        id: debugNode
        geometry: sceneShape.geometry
    }

car-rain

雨滴效果在汽车配置器演示项目中的应用。

汽车配置器演示项目已随 Qt 6.11 加入雨滴效果,并同步附带了雪花效果。

评论

Subscribe to our blog

立即体验 Qt 6.12!

点击此处下载最新版本:www.qt.io/download

Qt 6.12 LTS 现已发布,为应用程序开发者和设备制造商带来了新功能和改进。

我们正在招聘

点击此处查看所有职位空缺并关注我们的Instagram账号,了解成为#QtPeople的感受。