Qt Quick 粒子系统(九):外观随机性——大小、生命周期与颜色
目录
一、让粒子各有特色
上一篇讲解了位置、速度、角度三个"发射随机性"参数,解决了粒子"从哪来、往哪飞"的自然感问题。但粒子的外观同样需要随机性——如果所有粒子大小相同、颜色一致、同时消亡,看起来仍然像复制粘贴。
本文讲解三个"外观随机性"参数:大小随机性(sizeVariation)、生命周期随机性(lifeSpanVariation)、颜色随机性(colorVariation)。它们控制粒子"长什么样、活多久"的随机程度。
读完本文后,你将理解 sizeVariation 和 endSize 的区别、lifeSpanVariation 的边界行为、以及 colorVariation 在 HSV 色彩空间中的工作原理。
二、开发环境与版本说明
本文所有代码基于以下环境验证(验证日期:2026-06-15):
- Qt 版本:6.8.2
- 编译器:MinGW 64-bit
- 操作系统:Windows 11
- 构建工具:CMake 3.29
Variation 参数的 API 从 Qt 5 起稳定,Qt 6.5+ 均可直接运行本文代码。
三、原理分析:外观随机性
3.1 大小随机性:sizeVariation
sizeVariation 控制粒子初始大小的随机范围。数学模型与其他 Variation 一致:
实际大小 = size + random(-sizeVariation, +sizeVariation)
| 属性 | 含义 | 典型值 |
|---|---|---|
size |
基础大小(像素) | 10-20 |
sizeVariation |
大小随机偏移 | size 的 30-60% |
endSize |
消亡时的大小 | 0(渐消效果) |
sizeVariation vs endSize 的区别:
这两个属性经常被混淆,但它们控制的是完全不同的维度:
sizeVariation:控制粒子诞生时的大小随机性。每个粒子诞生时,大小在[size - sizeVariation, size + sizeVariation]范围内随机。之后粒子的大小按照从初始大小到endSize线性变化。endSize:控制粒子消亡时的大小。粒子在整个生命周期内,大小从诞生时的值线性变化到endSize。
组合使用:sizeVariation 让不同粒子有不同的初始大小,endSize 让每个粒子在生命周期内大小渐变。两者叠加产生丰富的视觉层次。
3.2 生命周期随机性:lifeSpanVariation
lifeSpanVariation 控制粒子存活时间的随机范围:
实际寿命 = lifeSpan + random(-lifeSpanVariation, +lifeSpanVariation)
| 属性 | 含义 | 典型值 |
|---|---|---|
lifeSpan |
基础寿命(毫秒) | 2000-5000 |
lifeSpanVariation |
寿命随机偏移 | lifeSpan 的 20-40% |
边界行为:当 lifeSpanVariation > lifeSpan 时,实际寿命可能为负值。负值会被 clamp 到 0,粒子立即消亡——视觉上表现为"有些粒子刚出生就消失了"。在 Variation_Lifespan.qml 的示例中,lifeSpan: 2000, lifeSpanVariation: 4000,实际寿命范围为 [-2000, 6000],负值部分全部 clamp 到 0。这意味着大约 25% 的粒子会立即消亡。
设计意图:大 lifeSpanVariation 制造"有的粒子长寿、有的粒子短命"的效果。短命粒子快速出现又消失,长寿粒子飘得更远,形成丰富的层次感。
3.3 颜色随机性
颜色随机性有两种实现方式,分别适用于不同的渲染器:
ImageParticle 的 colorVariation:
colorVariation 是 redVariation、greenVariation 和 blueVariation 的快捷属性——设置 colorVariation 等同于将三个 RGB 通道的变化量设为相同值:
实际红色 = color.red + random(-colorVariation, +colorVariation)
实际绿色 = color.green + random(-colorVariation, +colorVariation)
实际蓝色 = color.blue + random(-colorVariation, +colorVariation)
每个颜色通道在粒子之间的变化量最多为 colorVariation,范围是 0 到 1。0 表示所有粒子颜色完全一致,1 表示每个通道完全随机。一般 0.2-0.5 为自然变化。
ItemParticle 的自定义颜色:
ItemParticle 的 delegate 可以用 Qt.rgba() 或 Qt.hsla() 实现更灵活的颜色随机:
ItemParticle {
delegate: Rectangle {
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
每个粒子实例化独立的 delegate,Math.random() 在实例化时求值,所以每个粒子有不同的颜色。这种方式比 colorVariation 更灵活——可以控制随机的色相范围、固定饱和度和明度等。
四、代码实现
4.1 Variation_Size.qml:大小随机性
Emitter {
id: emitter
system: particleSystem
anchors.centerIn: parent
width: 1; height: 1
emitRate: 20
lifeSpan: 4000
size: 16
sizeVariation: 30
velocity: AngleDirection {
angle: 0
angleVariation: 360
magnitude: 100
}
}
size: 16, sizeVariation: 30 ——基础大小为 16 像素,随机偏移范围 ±30。实际大小在 [-14, 46] 范围内随机。负值被 clamp 到 0(不可见),所以大部分粒子大小在 0-46 之间。这产生了极大的大小差异——有些粒子很小(接近 0),有些粒子很大(46 像素)。
emitRate: 20 ——每秒只发射 20 个粒子,数量不多但每个粒子都很大,强调大小差异的视觉效果。
lifeSpan: 4000 ——4 秒的长寿命让粒子有足够的时间扩散到整个页面,大小差异在扩散过程中更加明显。
4.2 Variation_Lifespan.qml:生命周期随机性
Emitter {
anchors.centerIn: parent
width: 1; height: 1
emitRate: 20
lifeSpan: 2000
lifeSpanVariation: 4000
size: 24
velocity: AngleDirection {
angle: 0
angleVariation: 360
magnitude: 100
}
}
lifeSpan: 2000, lifeSpanVariation: 4000 ——基础寿命 2 秒,随机偏移 ±4 秒。实际寿命范围为 [-2000, 6000],其中负值部分(约 25%)被 clamp 到 0。
视觉效果:
- 约 25% 的粒子立即消亡(寿命为 0),在中心点一闪即逝
- 约 75% 的粒子存活 0-6 秒,扩散到不同距离后消亡
- 长寿粒子飞得更远,短命粒子在近处消亡,形成明显的"距离层次"
size: 24 ——所有粒子大小相同(无 sizeVariation),强调生命周期差异的效果。
4.3 Variation_Color.qml:颜色随机性
ItemParticle {
delegate: Rectangle {
width: 16; height: 16; radius: 8
color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
}
}
这个示例使用 ItemParticle 而不是 ImageParticle,因为 ItemParticle 的 delegate 可以用 Math.random() 实现完全随机的 RGB 颜色。
Qt.rgba(Math.random(), Math.random(), Math.random(), 1) ——每个通道独立随机,产生全色域的随机颜色。alpha 固定为 1(不透明)。
为什么不用 ImageParticle 的 colorVariation?
colorVariation 是在基础颜色的 HSV 空间中偏移,颜色变化范围受限于基础色。如果基础色是红色(hue=0),colorVariation: 0.5 只会让颜色在红色到橙色/品红之间变化,不会出现蓝色或绿色。
而 Qt.rgba(Math.random(), ...) 产生真正的全色域随机颜色,不受基础色限制。这种灵活性是 ItemParticle 的独特优势。
替代方案:如果想在 ImageParticle 上实现全色域随机,可以用 color: "white" 配合 colorVariation: 1。白色在 HSV 空间中 hue 为 0、saturation 为 0,colorVariation: 1 会让 hue 完全随机,实现全色域变化。但效果不如 Math.random() 精确。
五、运行效果
Variation_Size.qml:红色星形粒子从中心向四面八方扩散,大小差异极大——有的粒子很小(接近不可见),有的粒子很大(46 像素)。大小差异让粒子群有了"远近层次"的错觉。
Variation_Lifespan.qml:青色星形粒子从中心扩散,但消亡时间差异很大。部分粒子在中心点一闪即逝(立即消亡),部分粒子飞到页面边缘后才消亡(长寿)。形成"中心密集、边缘稀疏"的密度梯度。
Variation_Color.qml:全色域的彩色圆形粒子从中心向四面八方扩散,每个粒子颜色各异——红、绿、蓝、黄、紫……形成彩虹般的粒子流。
六、适用边界与限制条件
- colorVariation 范围是 0 到 1:0 表示所有粒子颜色完全一致,1 表示 HSV 空间中完全随机。一般 0.2-0.5 为自然变化
- sizeVariation 大于 size 时:实际大小可能为负值,被 clamp 到 0——粒子不可见。如果不想出现不可见粒子,确保
sizeVariation < size - lifeSpanVariation 大于 lifeSpan 时:部分粒子立即消亡(寿命 clamp 到 0)。如果是期望的效果(如闪烁光点),大值合适;否则建议
lifeSpanVariation < lifeSpan - endSize 和 sizeVariation 可以同时用:
sizeVariation控制初始大小的随机性,endSize控制消亡时的大小。两者叠加:不同粒子有不同的初始大小,但都渐变到同一个endSize - ItemParticle 的 Math.random() 在 delegate 实例化时求值:每个粒子拥有独立的 delegate 实例,所以结果各不相同
七、常见误区
“粒子大小差异不明显”——检查 sizeVariation 是否太小。设为 size 的 30-60% 才有明显差异,10% 以下几乎看不出区别。
“粒子刚出生就消失了”——检查 lifeSpanVariation 是否大于 lifeSpan。负值寿命被 clamp 到 0,部分粒子立即消亡。如果不需要这个效果,减小 lifeSpanVariation。
“颜色变化太单调,只有深浅不同”——colorVariation 同时偏移 RGB 三个通道,但如果基础色的各通道值接近(如灰色),偏移后颜色差异不大。用高对比度的基础色(如纯红、纯蓝)效果更明显。
“想让每个粒子颜色完全不同,但 colorVariation 不够”——colorVariation 受基础色限制。需要全色域随机时,用 ItemParticle 的 delegate + Qt.rgba(Math.random(), ...) 或 ImageParticle 的 color: "white" + colorVariation: 1。
八、总结
回到开头的问题:如何让粒子各有特色?三个 Variation 参数分别控制大小(sizeVariation)、生命周期(lifeSpanVariation)、颜色(colorVariation 或 Math.random())。核心公式不变:适中的 Variation + 合理的基础值 = 自然效果。
至此,粒子的"出生"参数(发射器、区域、方向、随机性)全部讲解完毕。下一篇进入粒子的"死后"环节——讲解物理影响器,如何在粒子发射后施加重力、摩擦和吸引等力场效果。
资源下载:qml_particlesystem —— 包含完整的、可运行的代码
系列目录
- 上一篇:Qt Quick 粒子系统(八):发射随机性——位置、速度与角度
- 本文:Qt Quick 粒子系统(九):外观随机性——大小、生命周期与颜色
- 下一篇:Qt Quick 粒子系统(十):物理影响器——重力、摩擦与吸引
更多推荐

所有评论(0)