ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

WLED PS Comet 用户修改详解:用内置 2D 粒子系统实现矩阵“流星 + 火焰“效果

WLED PS Comet 用户修改详解:用内置 2D 粒子系统实现矩阵“流星 + 火焰“效果 WLED PS Comet 用户修改详解用内置 2D 粒子系统实现矩阵流星 火焰效果【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED本文以 WLED 仓库中的 PS Comet 用户修改usermod文档 usermods/PS_Comet/README.md 为主体完整保留其安装方式与四个滑杆参数的说明并结合其全部源码 usermods/PS_Comet/PS_Comet.cpp仅 123 行与 WLED 内核的 2D 粒子系统 wled00/FXparticleSystem.h逐行拆解该效果的滑杆映射公式、生成/重生策略与火焰拖尾的实现原理。读完后可掌握如何在platformio_override.ini中启用该效果、四个参数在底层如何映射为粒子生命周期与下落速度以及如何把它接入任意自定义调色板。效果定位一个基于粒子系统的 2D 下落流星特效按照 README 的原始描述PS Comet 是一种类似Matrix的 2D 下落流星效果但叠加了火焰粒子模拟来增强流星拖尾的视觉表现。支持自定义调色板默认使用Fire调色板并支持 1px 宽的小型流星与 3px 宽的大型流星两种形态。模块目录结构非常精简只有三个文件文件作用PS_Comet.cpp效果函数、效果元数据字符串与 Usermod 注册类全部实现README.md安装方法与 4 个参数说明library.jsonPlatformIO 库清单名称 PS CometlibArchive: false不打包归档源码直接编译从源码结构看该效果没有自研粒子逻辑而是完全构建在 WLED 内置的ParticleSystem2D引擎之上定义于 wled00/FXparticleSystem.h、实现于 wled00/FXparticleSystem.cpp自身只负责每一列一颗流星的状态机。这也是理解本 usermod 的关键它本质上是一个粒子系统的驱动脚本。安装与启用README 给出的启用方式是在platformio_override.ini中添加构建参数custom_usermods ps_comet如果已经在用其他 usermod则把ps_comet追加到列表中custom_usermods audioreactive ps_comet重新编译固件后Web UI 的效果列表中应出现 PS Comet。从源码可以看到注册机制PS_Comet.cppclass PSCometUsermod : public Usermod { public: void setup() override { strip.addEffect(255, mode_pscomet, _data_FX_MODE_PSCOMET); } void loop() override {} }; static PSCometUsermod ps_comet; REGISTER_USERMOD(ps_comet);要点REGISTER_USERMOD(ps_comet)宏注册全局实例其实例名ps_comet与custom_usermods中的开关名一一对应——注意目录名是大写PS_Comet而构建开关必须写成小写ps_comet拼错会导致固件中根本不含该效果效果通过strip.addEffect(255, ...)以 usermod 预留效果 ID255注册setup()在启动时执行一次loop()为空每帧工作全部由效果函数完成。运行前提由源码守卫条件决定PS_Comet.cpp必须应用于2D 段矩阵映射的 segment且虚拟宽高均不小于 2粒子系统内存分配必须成功任一条件不满足时效果回退为SEGMENT.fill(SEGCOLOR(0))的纯色填充FX_FALLBACK_STATICPS_Comet.cpp即降级为静态色而不是报错。因此把它应用到 1D 灯带上不会崩溃只是显示单色。效果元数据字符串滑杆、默认值与调色板每个 WLED 效果随函数一起注册一个元数据字符串PS Comet 的是PS_Comet.cppstatic const char _data_FX_MODE_PSCOMET[] PROGMEM PS CometFalling Speed,Comet Frequency,Large Comet Probability,Comet Length;;!;2;pal35,sx128,ix255,c132,c2128;其字段依次是效果名PS Comet4 个滑杆名称Falling Speed,Comet Frequency,Large Comet Probability,Comet Length勾选选项区;;表示无效果标志区!与2其中2声明其为 2D 效果以及默认值区pal35,sx128,ix255,c132,c2128。这些默认值如何被加载可以在内核 wled00/FX_fcn.cpp 的Segment::setMode()中确认切换效果时内核用extractModeDefaults()依次解析sxspeed、ixintensity、c1/c2/c3custom 滑杆、o1..o3勾选项、pal调色板等键并写入对应段属性。因此本效果的默认状态为pal35Fire 调色板内核效果 Fire 2012 同样使用pal35见 wled00/FX.cpp与 README 默认 Fire 一致sx128Falling Speed 默认 128ix255Comet Frequency 默认 255最高c132Large Comet Probability 默认 32约 12.5%c2128Comet Length 默认 128居中。调色板是可替换的由于颜色统一由粒子系统按段调色板渲染README 所称支持自定义调色板指在 Web UI 中为段选择任意调色板即可整体换色例如换成冷色调得到蓝色数字雨无需改动代码。参数到代码的完整映射表README 列出的 4 个参数与源码中的公式对应关系如下均出自 PS_Comet.cpp滑杆UI 名称段字段源码公式取值范围与效果Falling SpeedSEGMENT.speedfallingSpeed 1 (speed 2)L620..255 → 1..64 子像素/帧。粒子系统以 64 子像素 1 像素PS_P_RADIUS见 FXparticleSystem.h因此速度上限约 1 像素/帧Comet FrequencySEGMENT.intensitydelay 2040 - (intensity 3)再叠加hw_random16(delay)抖动L54-L55基础生成间隔 2040msintensity0线性降到 0msintensity255随机抖动使间隔不均匀、更自然Large Comet ProbabilitySEGMENT.custom1SEGMENT.custom1 hw_random8(254)L57-L61等价于约custom1/255的生成概率默认 32 ≈ 12.5%且要求命中列不是首/末列两侧必须有邻列可生成侧流星Comet LengthSEGMENT.custom2主流星maxLife 16 (c2 2)、minLife maxLife 1、ttl 16 - (c2 4)L90-L92同时火焰强度updateFire(max(255U - c2, 45U))L10516..78 帧的最大寿命与 9..16 帧的火焰 ttl 共同拉长/缩短拖尾火焰强度在 255..45 之间反向调节注意四个滑杆并非各自独立Falling Speed 同时决定下落速度与火焰粒子的向上发射速度source.vy (speed 5) - fallingSpeedComet Length 同时作用于粒子寿命与火焰强度两处源码注释也明确说明 Slider 4 controls comet length via particle lifetime and fire intensity adjustments。核心循环初始化、生成门控与重生策略初始化与状态持久化效果函数mode_pscomet()每帧被调用一次。首次调用SEGMENT.call 0时执行一次性初始化PS_Comet.cppif (SEGMENT.call 0) { // Initialization // Try to allocate one comet for every column if (!initParticleSystem2D(PartSys, SEGMENT.vWidth())) { FX_FALLBACK_STATIC; // Allocation failed or not 2D } PartSys-setMotionBlur(170); // Enable motion blur PartSys-setParticleSize(0); // Allow small comets to be a single pixel wide } else { PartSys reinterpret_castParticleSystem2D *(SEGENV.data); }initParticleSystem2D(PartSys, SEGMENT.vWidth())按每列申请一个发射源source即最多一列一颗流星粒子系统的内存指针保存在段的SEGENV.data中后续帧直接取回复用因此流星在段内切换效果前可以持续存在setMotionBlur(170)头文件注释说明运动模糊在取值 100 时动画更平滑且仅在粒子尺寸为 0 时可用FXparticleSystem.h下一行setParticleSize(0)恰好满足该前提同时保证小型流星可以细到 1 像素。生成门控时间窗口 邻列互斥每帧先随机挑一个候选列再做三重门控PS_Comet.cppuint32_t numComets PartSys-numSources; uint32_t chosenIndex hw_random(numComets); if ( strip.now nextCometCreationTime || !has_fallen_off_screen(chosenIndex - 1) || !has_fallen_off_screen(chosenIndex) || !has_fallen_off_screen(chosenIndex 1) ) { chosenIndex NULL_INDEX; } else { uint16_t cometFrequencyDelay 2040 - (SEGMENT.intensity 3); nextCometCreationTime strip.now cometFrequencyDelay hw_random16(cometFrequencyDelay); }未到nextCometCreationTime由 Comet Frequency 计算含硬件随机数hw_random16抖动则本帧不生成候选列及其左右邻列必须都已完全落下屏外否则取消本次生成——这是避免相邻流星贴在一起的互斥机制也解释了为什么大型流星占 3 列只允许在中间列生成。落下屏外的判据PS_Comet.cpp是source.y -maxY即源点位置低于屏幕底部再一个完整屏高确保拖尾粒子也基本消散后才允许该列复用。重生位置与大型流星的 3 列结构被选中的列在顶部重生PS_Comet.cppsourceParticle.x i * PartSys-maxX / (SEGMENT.vWidth() - 1); // 列号 → 子像素坐标 sourceParticle.y PartSys-maxY (2 * fallingSpeed); // 略高于顶边初始 y 故意设在顶边之上2 * fallingSpeed子像素处源码注释解释为 Spawn a bit above the top to avoid popping into view避免流星在边界突兀出现。若本帧触发大型流星canLargeCometSpawn则chosenIndex两侧邻列也同步重生为侧流星但参数不同主流星寿命由 Comet Length 滑杆决定见上表侧流星固定maxLife18 / minLife14 / ttl16并且整体上移 1 像素sourceParticle.y 2 * PartSys-maxY / (vHeight - 1)使 3 列呈现错落的 V 形头部——这就是 README 中3px wide大型流星的实现方式它不是一颗变宽的粒子而是三个并排、寿命稍短的发射源。活跃流星下落 逐帧喷火仍在屏内的流星每帧执行PS_Comet.cppsourceParticle.y - fallingSpeed; // 向下下落 source.vy (SEGMENT.speed 5) - fallingSpeed; // 向上负 y的发射速度 PartSys-flameEmit(PartSys-sources[i]); // 以火焰模式喷发粒子由于粒子系统坐标中 y 减小为向下与重生 y 为正、下落做减号一致发射速度取负值使火焰粒子相对头部向上飘散形成跟随头部的上升拖尾正是Matrix 雨滴 火焰观感的核心flameEmit与帧末的PartSys-updateFire(intensity)L105构成粒子系统的火焰模拟管线按帧更新粒子运动、寿命与按 ttl 映射的颜色再渲染到段缓冲。Comet Length 滑杆通过同时压大寿命c2 增大 → maxLife 增大、减小火焰 ttl 与火焰强度255 - c2下限 45来改变拖尾长度与源码注释描述一致。与 2D 粒子系统的资源约束该效果的所有粒子/发射源数据结构定义在 wled00/FXparticleSystem.h单个粒子PSparticle10 字节子像素坐标、ttl、速度、色相/饱和L81-L89发射源PSsource20 字节寿命范围、源粒子、发射速度等L131-L140。每平台内存上限L43-L55平台最大粒子数MAXPARTICLES_2D最大发射源MAXSOURCES_2DESP826625624ESP32-S2102464其他 ESP322048128由此可以推断两条实用结论列数即发射源数。PS Comet 按vWidth()申请源因此超宽矩阵如 128 列的普通 ESP32或大尺寸矩阵ESP8266 上 24 列会因内存不足导致initParticleSystem2D失败效果回退为纯色填充此时缩小段宽度或改用 ESP32 目标即可。每帧调用PartSys-updateSystem()PS_Comet.cpp刷新尺寸与数据指针允许段尺寸改变后继续运行。调参与验证清单结合默认值sx128, ix255, c132, c2128, pal35与上述公式常用调参方向密度Comet Frequency 调低 → 基础生成间隔从 0ms 拉长到 2040ms含等量随机抖动流星更稀疏调高则近乎连续生成仅受邻列互斥限制宽度Large Comet Probability 从 32约 12.5%调高可明显增加 3px 大型流星调为 0 则全部为 1px 细流星拖尾Comet Length 调高 → 主流星粒子寿命更长至多 78 帧、火焰强度降低拖尾更细长调低则短促有力换色直接在 Web UI 改段调色板README 所述支持自定义调色板即指此不需要重编译。验证与排查编译后 Web UI 效果列表出现 PS Cometstrip.addEffect注册成功选中一个 2D 段的矩阵效果应显示多列独立下落、带火焰拖尾的流星若整段为纯色按源码守卫依次排查段是否为 2D、虚拟宽高是否 ≥2、平台内存是否足够对照上表的上限1D 灯带上该效果按设计降级为SEGCOLOR(0)纯色填充属正常行为而非故障。小结PS Comet 是一个小而完整的粒子系统驱动型效果范例README 承诺的四个滑杆参数、小型/大型流星与默认 Fire 调色板在 usermods/PS_Comet/PS_Comet.cpp 中分别落为fallingSpeed、cometFrequencyDelay、canLargeCometSpawn与maxLife/ttl updateFire四组公式元数据字符串的pal35,sx128,ix255,c132,c2128提供默认值并由内核Segment::setMode()wled00/FX_fcn.cpp解析加载。理解这套元数据字符串 → 段字段 → 粒子系统调用的链路后既可以在矩阵灯带上快速得到可定制的火流星效果也可以将其作为编写其他基于ParticleSystem2D的 WLED 效果的参考模板。【免费下载链接】WLEDControl WS2812B and many more types of digital RGB LEDs with an ESP32 over WiFi!项目地址: https://gitcode.com/GitHub_Trending/wl/WLED创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表