ba-click-fx-desktop

September 4, 2026 · View on GitHub

ba-click-fx-desktop 是从零实现的 Windows 原生桌面点击特效。项目不复用 ba-click-fx 的 JavaScript、WebGL 或 WebGPU 渲染代码;Unity/游戏资源是视觉真值, Web 版本只作为历史行为对照,不定义本项目的配置、IPC 或单位合同。

网页版 ba-click-fx

ba-click-fx 是面向浏览器的蔚蓝档案点击特效与鼠标拖尾库, 从 Unity FX_Touch.prefab 的粒子系统和 TrailRenderer 参数移植而来。它使用 WebGL2 作为主要渲染路径, 并提供 WebGPU、Canvas 2D、软件 Bloom 和原生辉光等回退方案;在浏览器和显示链支持时,还可以尝试 WebGPU HDR 输出。

网页版可以通过在线演示直接体验,也可以作为浏览器扩展安装,或通过 npm、CDN 集成到自己的网页中。它提供点击特效、拖尾、主题颜色、透明度、尺寸、Bloom 和输入采样等运行时配置,适合网页和浏览器扩展场景。

本项目的桌面版与网页版共享 Unity/游戏资源这一视觉参考,但桌面版使用 C++20、Win32、Direct3D 11、HLSL 和 DirectComposition 重新实现渲染、输入和透明覆盖层;两者的配置、IPC、渲染后端和单位合同彼此独立。

Release Host 运行时是单文件:Visual C++ 运行库静态链接,Circle、Grad Ring、Triangle Atlas、Trail 四张参考纹理的 RGBA8 texel 以 raw LZ4 Block 无损压缩为 C 字节串,直接编译进 EXE。启动时逐张分配 无需预清零的输出缓冲区,执行一次有界解压并直接创建 D3D11 immutable sRGB 纹理;上传返回后立即 释放 CPU texel。该路径没有 Base64、PNG 容器、WIC 解码或临时图片文件。材质 HLSL 也嵌入程序; 运行不读取 Unity 工程、游戏目录或旁置 shader/图片文件,只使用 Windows 自带的 D3D11、 DirectComposition 和 D3DCompiler 系统组件。独立的 Control Center 使用纯 Win32 Common Controls, 不需要 Windows App SDK 或其他旁置运行时。

当前架构版本是 v0.3,状态为 Proposed。当前源码产品版本为 0.2.11,已具备 Host、原生 Win32 Control Center、本地 IPC 与完整便携包流程;当前人工特效审核和支持合同以单主屏 SDR 下的三种渲染模式 为准。涉及 DirectComposition、Windows Graphics Capture、HDR/Advanced Color 和多适配器的结论, 必须取得仓库中定义的 Spike 证据或接受明确的 fallback 后,相关 ADR 才能标记为 Accepted。

Host 现在会把主协调屏摘要和稳定排序的逐显示器运行状态写入支持报告,并通过严格的 GetDisplayState schema 4 提供拓扑完整性、配置/应用代次、来源身份、物理/捕获刷新率、DRR、GPU、 颜色查询 HRESULT、SDR white level、请求/解析/实际输出、cadence/output fallback、WGC、故障状态,以及 每个显示会话近 5 秒的 Active-FX ROI primary/recording-rebuild 工程快照。 报告还固定记录 Host 启动时的快捷键注册掩码、四项注册结果/Win32 错误与清理错误,并以 Hotkeys.StateScope=startup 明确其不是导出时的实时状态。 Control Center 只展示 Host 报告的实际能力;未知能力保持未知,不会根据用户请求或代码路径伪装成已支持。 这些字段只用于后续 HDR/显示 Spike 的能力证据;Support.HDR=not-supported 在完整输出矩阵通过前保持 不变,亮度为零时也会显式标记为未知,而不会把零值解释成显示器真实亮度。

WGC 的 FP16 scRGB 背景像素使用独立的背景 reference white 转入 Unity 相对工作空间;粒子、材质、 Trail 和 Bloom 继续按游戏合同在线性 FP16 中计算。最终呈现阶段才使用目标屏的输出 reference white 区分 SDR/HDR 映射。两类白点互不替代;HDR/WCG 下背景白点未知时保留捕获会话预热,但背景不得参与 合成,当前帧安全回退 FX-only。

冻结的技术方向

  • C++20、Win32、D3D11、HLSL、DirectComposition。
  • D3D11 immediate context 只由 Render Owner 使用。
  • 一个 DXGI Adapter 定义一个资源域;跨适配器资源不隐式共享。
  • Windows Graphics Capture 只由 background-aware 模式使用;它不是基础点击特效的硬依赖,失败时 回退到内部 FX-only transport。
  • background-awarerecording-compatiblelight-background 是唯一的产品渲染模式。前者使用 WGC 和完整的 Differential Bloom;recording-compatible 关闭 WGC,拟合 Web 版透明覆盖层的 visual-maxbright-core0.90 Alpha 上限和 source-over;light-background 使用同一颜色策略, 但将桌面 Alpha 上限收紧为 0.85
  • performance.effectsMode 提供 fullcore 两个特效计算档位。core 面向低性能机器保留中心圆盘、 圆环、点击/拖拽碎片和拖尾,只跳过 Bloom 计算;它固定使用保守 SDR、60 FPS、FX-only 路径并关闭 WGC, 不代表完整背景合成或 HDR 能力。
  • 最终透明交换链使用 FP16 扩展预乘输出;普通 SDR 下不得承诺白底仍有加法余量。
  • 三角碎片保留清晰的 HDR 直接能量,同时按游戏 FX_SHADER_Additive_0 进入全场景 Bloom, 因此既有锐利核心也有对应的模糊光晕。

桌面版的 DirectComposition overlay 没有浏览器 Screen API 的逐像素等价物。只有 background-aware 在 WGC 样本有效时能把异步桌面纹理带入合成;recording-compatiblelight-background 是没有捕获背景时的确定性传输策略,不能宣称对任意桌面像素逐点还原。

文档入口

项目状态

仓库已经进入首个可运行版本的人工审核阶段。文档中的 ProposedVerifiedAccepted 是严格状态,不代表完成百分比:没有证据的能力不会因为代码路径存在、配置项存在或 日志显示为可用而被宣称支持。

本地可用下列命令核对 Unity 外部证据。脚本只读取并校验哈希,不会复制或修改游戏资产:

cmake --build build\vs2026 --target verify_unity_reference

构建与测试

首版固定使用 C++20;本机验证工具链为 Visual Studio 2026 与 Windows SDK 10.0.26100。推荐使用 仓库预设完成全新 Release 配置、构建和测试:

cmake --workflow --preset release-verify

日常只验证桌面 Host 时使用按目标构建,避免触发包含全部测试和 Spike 的 ALL_BUILD

cmake --build --preset host-release --parallel 4

release-verify 仍然保留完整 Release 构建和 CTest 流程;它不是快速迭代命令。

普通 x64 预设启用 Spout2,并要求 VCPKG_ROOT 指向 Spout2 依赖; x64-slim 预设通过 BAFX_ENABLE_SPOUT2=OFF 构建不含 Spout2 的精简版。 精简版仍保留完整特效和控制中心,但不会显示 Spout2 输出开关。对应的打包脚本可传入 -Slim,生成文件名带有 -slim 后缀。

官方 GitHub Release 只发布带 Spout2 的 Full 版四个资产:便携 ZIP、便携 ZIP 的 .sha256、 单文件安装器和安装器的 .sha256。Slim 版保留源码构建、测试和本地打包入口,不发布预编译 Release 资产。

标准构建的 OBS 输出是透明扩展预乘的 FX-only 层。OBS 需要把游戏/桌面捕获置底,并把绑定 ba-click-fx-desktop 的 Spout2 源置顶、设为 Premultiplied Alpha,来源混合方式保持 Default、混合模式保持 Normal。 插件探测、旧场景 迁移和本机验收步骤见 docs/OBS_SPOUT2.md

.github/workflows/windows-build-compat.yml 使用 VS2022 以 Windows SDK 10.0.19041.010.0.22621.010.0.26100.0 构建 Host、Control Center 与 Identity Signer 的完整二进制;每个 job 还会记录 runner 实际安装的 Include/Lib SDK 清单。19041 是最低旧 SDK 基线,22621 是中间 Windows 11 SDK,26100 是当前 runner 清单中的最高 SDK。该矩阵只证明编译兼容,不代表 Windows build 28000+ 的运行时能力或 WGC Session-local exclusion;Windows 11 API 始终采用运行时能力探测, 旧 SDK/Windows 10 构建不能通过裁剪产品目标来规避这些功能。

DirectComposition smoke test 需要交互式桌面,因此默认不进入普通 CTest:

cmake --build --preset debug --target smoke_desktop

启用 BAFX_ENABLE_DESKTOP_SMOKE_TESTS=ON 时,smoke 会生成一次确定性中心点击,实际经过 Unity 材质 shader、MRT、FP16 预乘交换链和 DirectComposition present。单独查看效果可运行:

build\x64\src\desktop\Debug\ba-click-fx-desktop.exe --demo-click

Overlay 不抢焦点且保持鼠标穿透;右键通知区域图标可退出,也可在控制中心的“快捷键”页绑定退出键。 快捷键默认全部未绑定,旧的两个固定 F12 退出组合和轮询兜底已移除。当前 smoke 仍不等同于 HDR、跨适配器或 WGC 的 Spike 已通过。

便携版

下面的命令会先构建 Release Host 和原生 Win32 Control Center,再将两个 EXE、支持文档和逐文件 SHA-256 清单打入 ZIP;脚本完成前会自动运行包验证。它只要求 cmake.exe 可用:

pwsh -NoProfile -ExecutionPolicy Bypass -File .\tools\package-test-bundle.ps1

默认输出到 artifacts\local\ba-click-fx-desktop-<version>-Portable-windows-x64.zip,并在同目录生成 .sha256 文件。解压后必须保留目录结构:先启动 ba-click-fx-desktop.exe,再启动 BAFX.ControlCenter.exe。Control Center 只依赖 Windows 自带的 User32、Comctl32 和配置 IPC, 可以直接复制该 EXE 运行,但需要与 Host 放在同一目录才能使用“启动 Host”按钮。连接后同一按钮会 切换为“关闭 Host”,通过 IPC 请求正常退出,并等待 Host 的单实例生命周期真正结束后才允许再次启动。 “重置默认”会在确认后一次性恢复其他持久化设置,保留 Host 已保存的快捷键,不改变当前暂停或运行状态。

轻量视觉审核包

如果只需要审核点击和拖尾画面,不需要控制面,请使用 Host-only 包入口:

pwsh -NoProfile -ExecutionPolicy Bypass -File .\tools\package-host-review-bundle.ps1

脚本从 Release Host 单独组装三文件审核包,并将经过验证的 ZIP 放到 artifacts\local\host-visual-review\<commit>\。该包只包含 Host、许可证和支持说明, 通常约 0.4 MB;完整便携包现在也只包含两个原生 EXE,压缩后约 0.7 MB,不再携带 Windows App SDK 旁置运行时。

普通用户安装器

Release 页面提供单文件 *-setup-windows-x64.exe 安装器。普通用户不需要安装 Visual Studio、Windows SDK、Inno Setup 或 PowerShell 依赖包;安装器已经包含 Host、Control Center、 未签名的 Sparse Package 模板、原生签名器和安装脚本,不包含预签名 MSIX、公钥证书或私钥。

  1. 从 Release 下载与系统匹配的 *-setup-windows-x64.exe,同时下载同名 .sha256,按页面提供的哈希校验文件。
  2. 双击安装器并确认一次 UAC。安装器会把程序放到 Program Files,为当前用户注册方案 C Package Identity, 在开始菜单和桌面创建 Control Center 快捷方式,然后打开 Control Center。
  3. 在 Control Center 中点击“启动 Host”,再按需选择“背景感知”“录屏兼容拟合”或“浅色背景优化”。 关闭 Control Center 不会停止 Host;可以从通知区域退出 Host。
  4. 卸载时使用开始菜单中的卸载项或 Windows“已安装的应用”。默认保留程序目录下的 data 配置,重新安装 后仍可继续使用;如需彻底清理,请在卸载前手动备份并删除该目录。

从 0.2.5 起只提供手动版本检查,不是自动更新器。从 0.2.4 或更早版本首次升级时,旧 Control Center 尚没有“检查更新”入口,仍需用户前往官方 Release 页面 手动下载并运行新安装器,或手动替换完整便携目录。不要混用不同版本的 Host 与 Control Center。

该安装器使用目标机生成的本机证书为 Sparse Package 签名,不是公有代码签名。Windows SmartScreen 可能显示 “Unknown Publisher”,这是预期提示。安装器只把公钥加入 LocalMachine\TrustedPeople,签名验证完成后立即删除 LocalMachine\My 中的证书和不可导出私钥;不要从 Release 单独下载或安装证书、MSIX、私钥或 SDK 工具。若没有管理员权限, 请改用上面的便携 ZIP,直接解压运行即可,但便携版没有 Package Identity,无法承诺无边框 WGC。

Host 控制面

首个产品化垂直切片已经接入版本化配置和本地 Named Pipe。portable Host 会在主程序 ba-click-fx-desktop.exe 同目录创建 BAFX.config.jsonba-click-fx-desktop-support.log,首次保存自定义特效 Profile 时再创建 fx-profiles 子目录; Identity 安装版则将这些文件和目录放入同一目录下可写的 data 子目录。每个自定义 Profile 对应 fx-profiles/<名称>.json 一个文件,内容是完整、平面的 EffectsConfig JSON;Host 是这些文件的唯一写入者。 支持报告也会被限制在这棵目录树内。运行时不再使用 %LOCALAPPDATA%、当前工作目录或其他用户目录保存数据。Host 使用 Local\BAFX.Host.v1 互斥体保证单实例。

首次生成的 schema 20 配置将 background.mode 设为 background-awarebackground.allowSystemBorder 设为 truedisplay.hdrEnabled 设为 false,并以 performance.framePacing=match-displayinput.trailOnlyWhilePressed=trueinput.samplingRateHz=0 保持跟随显示器刷新率、按住拖尾且不额外限制输入 Move。显示刷新率缺失或无效时, match-display 保守回退到 60 FPS;只有显式选择 unlimited 才不设置额外最小帧周期。 当前配置要求字段完整的显式 schemaVersion=20;14 至 19 会按固定顺序迁移到当前版本, 其他版本、缺少 section、未知字段和枚举别名都会被拒绝。Host 记录错误后仅在内存中使用当前默认值, 不会猜测未知格式。只有 background-aware 会启用 WGC;WGC 或捕获排除路径失败时,Host 将当前批次回退到内部 FX-only coverage transport,支持报告仍记为 fallback-fx-only。这个故障回退不是一个可选的产品模式, 也不会把背景感知配置改写成其他模式。 portable EXE 不带 package identity,因此不会把无边框捕获 capability 伪装成已支持。允许系统边框时, WGC 可以在 Windows 要求隐私提示的情况下启动;可见边框会在日志中记为 system-border=visible-allowed。用户可以在 Control Center 中取消勾选“允许黄色捕获边框”;此后 Host 会在 StartCapture 前请求并确认无边框会话,接口缺失、权限不足或 Windows 仍要求系统边框时直接回退 FX-only,不会先启动带黄色边框的会话。无论该开关如何设置,Overlay 的跨进程鼠标穿透都具有更高 优先级,任何自排除冲突都必须回退 FX-only。

BAFX.ControlCenter.exe 已作为独立的 Win32 进程接入该 Pipe。Host 保持运行时,Control Center 可以读取状态、暂停或恢复特效。五个顶层页面分别为“基础”“高级”“显示与性能”“快捷键”和“系统”。基础页提供启用状态、 点击特效、鼠标拖尾、拖尾常驻、完整/核心性能模式、效果大小、拖尾长度、拖尾宽度、输入采样率上限、Bloom 强度与 Bloom 质量, 并管理背景模式、指针排除和系统捕获边框;右侧的特效预设区可以选择四个内置 Profile,或按名称应用、 保存和删除自定义 effects-only Profile。高级页再按“时间与透明度”“粒子与材质” “圆环参数”“点击碎片”“Bloom 参数”“分层开关”分成六个二级页面。分层页可分别隐藏中心圆盘、 圆环、点击碎片、拖尾碎片、拖尾线和 Bloom;关闭 Bloom 会旁路整条 Bloom 金字塔,但保留直接材质。 所有控件只使用项目原生的 effects.* 配置路径,例如 effects.diskRadiuseffects.diskLifetimeMseffects.ringsCounteffects.ringsLifetimeMseffects.ringsRadiusMineffects.ringsRadiusMaxeffects.ringsAngularVelocityMultipliereffects.ringsRotationDirectioneffects.shardsClickCounteffects.shardsSizeMineffects.shardsSizeMaxeffects.trailOpacity。两个碎片尺寸字段由原生模拟统一应用于点击与拖尾碎片。其余两页提供 透明度、点击/拖尾时间倍率、拖尾寿命,以及 Bloom 扩散、阈值、软阈值和亮度上限。“显示与性能”页通过 GetDisplayState 选择并查看每个显示会话的 实际边界、DPI、物理/捕获刷新率、DRR、颜色查询、SDR white level、色彩/输出回退、WGC 和故障状态, 并提供默认关闭的全局 HDR 请求、默认关闭的“启用自适应 Active-FX ROI(实验)”,以及 match-display60120144unlimited 五种 performance.framePacing 策略。具有稳定 DisplayConfig 标识的显示器可以启用独立设置,分别控制特效、HDR 请求和帧率策略;关闭独立设置后恢复继承全局值。 没有稳定标识的会话仍可查看,但逐屏写入控件保持禁用。完整拓扑下,选择器还会列出未连接显示器的 遗留 override;这些条目没有伪造的运行状态,只能通过现有原子命令删除。诊断文本使用可滚动只读区域; 系统页提供“清理诊断日志”按钮,确认后通过 ClearLogs 删除当前日志和轮转备份,并显示删除文件数、 释放字节数和失败文件数。系统页的“版本与更新”区域分别显示 Control Center、Host、安装状态和 最新公开版本,并提供手动“检查更新”、“打开 Release”和常驻可用的“打开项目仓库”。仓库入口旁会提示 用户可前往项目仓库点 Star。Control Center 的通知区域菜单在 Host 已连接时 可直接暂停或恢复特效;Host 断开时该项置灰。该操作复用现有运行时命令,不写入配置,也不改变下一次 Host 启动时的默认运行状态。Active-FX ROI 工程面板在页面可见时每秒 刷新选中显示器的 primary/recording-rebuild 路径、回退原因、近 5 秒帧数与像素、dirty/aligned rect、 guard/phase、prefilter/downsample/upsample/resolve 分阶段像素和 Prefilter/Pyramid/FinalComposite GPU p50/p95;离页停止轮询,样本超过 3 秒显示 stale。这些数字描述实际执行路径和测量样本,不会据像素 比例推导 GPU 节省。 选择器刷新后尽量保留同一显示器;状态缺失或解析失败时显示错误,而不会把请求状态显示为实际能力。

Host 和 Control Center 从 0.2.5 起共享同一产品版本合同。Host 的 GetState.productVersion 必须是 与当前 Control Center 完全相同的规范 MAJOR.MINOR.PATCH;字段缺失、格式错误或版本不一致时, 控制中心会显示双方版本并禁用设置写入,但“启动 Host”/“关闭 Host”仍可用。这样可以完成混合版本 修复,而不会让旧控制面向新 Host 写入未经确认的配置。

安装状态的显示含义如下:有效安装状态中的产品版本与 Package 版本一致且匹配 Control Center,或已 从同样有效的备份成功恢复时为“安装版”;主安装状态和备份都不存在时为“便携版”;状态损坏、两种 版本冲突、安装版本与控制中心不同,或只剩备份等部分升级情况均为“安装状态异常”。异常状态不会 回退显示为便携版,应重新运行当前版本安装器修复。

“检查更新”只有在用户点击后才查询 GitHub 的最新公开正式 Release;启动、连接 Host、刷新状态和 托盘恢复都不会触发网络请求。它只比较版本,不会自动下载 Release 资产、运行安装器或改写文件。 “打开 Release”始终打开固定的 官方最新 Release 页面, 不采用网络响应中的资产 URL 或跳转目标。 “打开项目仓库”不依赖更新检查结果,始终打开固定的 官方项目仓库。 渲染配置调整在下一帧交给 Host;快捷键保存则在 IPC 响应前完成注册准备、原子写盘和切换。“拖尾常驻”默认关闭;开启后 无需按住鼠标,普通移动也会生成纯拖尾,但不会伪造点击圆盘或圆环。这是桌面版的原生产品增强, 不属于游戏原脚本的按压 FX 路径。数值控件会合并连续拖动后的写入,避免为每个滑块像素都写一次配置。 effects.bloomIntensity 是 Unity Bloom 强度标量,默认值为 1.7、有效范围为 0..10,不是相对 1.0 的倍率。 Bloom 质量只是 diffusion 的派生预设:紧凑、适中、原版、极宽分别对应 4/6/7/10,其他值显示为“自定义”。 Active-FX ROI 当前裁剪纯特效 Bloom 的 prefilter 和完整 down/up 金字塔,并为 resolve 生成逻辑有效矩形。 在 steady pure-FX primary 中,经过完整合同验证的 partial final output 只对 resolveRect 执行 Context1 ClearView、绘制和 Present1 dirty rect 提交;矩形移动时会合并并清理上一帧可见区。 warmup、background-aware、recording-rebuild、WGC、Spout2 格式转换以及任何回退路径仍执行完整输出和普通 Present。ROI 继续默认关闭并标记为实验性;WARP 和 dirty Present 计数只验证渲染器与路径合同,不证明 DWM 可见结果、功耗收益或跨硬件表现。

Active-FX ROI 旧 capture schema 2/3 与对应报告的 FAIL 是历史结果,不追溯改判。新 report schema 4 将重复反映同一同步等待的四项 Frame/Present 条件改为 non-blocking advisory;真实硬件性能与输入延迟 仍为 Not Run,因此当前不声明整机提速。采集器仍会在开始及每个 ABBA 块前检查系统空闲度并 fail-closed。

控制中心的“重置默认”按钮会先请求确认,再用内置默认 schema 替换快捷键以外的持久化配置。它保留 Host 已保存的快捷键,也不会恢复已经暂停的特效;需要继续显示时仍应单独点击“恢复特效”。

Host 在每次输入消费/交换链呈现更新中,为按压 FX 锁存一份帧边界当前鼠标位置,并用同一份 renderTime 执行本轮模拟动作。普通调用顺序为 Down→Held→Up;普通 Up-only 释放帧的 Held 为 false, 因此不会先把该帧 Move 应用为按住移动再释放。含任一边沿的帧也不会用边沿后的尾随 Move 重启常驻拖尾。Raw Input 的 Down/Up/Cancel 仍按原顺序无损保留,仅用于诊断和 native 扩展;严格效果路径将它们归约为单帧 Down/Held/Up 布尔态,并固定按 Down→Held→Up 执行,Cancel 最后作为 native 硬边界处理。Unity 2021.3.45f1 Player 黑盒已确认 Down-Up-Down 在聚合帧中三态同时为 true;其他边沿排列及游戏使用的 Unity 2021.3.56f2 仍未验证。没有待消费的位置时不会仅为输入适配而读取光标;按住静止期间由模拟 advance 推进距离发射的时间基线。

“输入采样率上限 (Hz)”默认值 0 表示不额外限频;1..1000 仅使用位置样本的消息分派 QPC 推进 可选输入采样相位。QPC 不决定模拟动作时间、帧态归约、严格路径执行顺序或释放时刻。30 Hz 是低功耗视觉 审核预设,15 Hz 折线更明显,60 Hz 更平滑;这些是人工审核入口,不是从 Prefab 提取出的固定客户端 帧率,也不会修改 Unity TrailRenderer 的 m_MinVertexDistance=0.01time=0.3widthMultiplier=0.005

控制中心也会显示三个渲染模式(显示名依次为“背景感知”“录屏兼容拟合”“浅色背景优化”),以及 “允许黄色捕获边框”复选框。它们对应的 wire values 分别为 background-awarerecording-compatiblelight-background;切换到后两项会关闭 WGC。新配置默认请求 background-aware 并允许 Windows 显示捕获边框;用户可取消勾选以要求无边框捕获。这不构成 WGC、 录屏兼容性或 HDR 的支持声明;关闭边框后若无边框 WGC 无法安全建立,Host 必须保持或回退到内部 FX-only transport。

“录屏兼容拟合”固定使用截图中 Web 版设置的原生对应:browser-overlay 透明覆盖层、 visual-max Alpha 策略、bright-core 颜色补偿、0.90 Alpha 上限、source-over 宿主合成, 并按未知透明背景处理,不让 WGC 样本进入最终 pass。原生桌面没有 Web 的 DOM 背景表面;这里由 DirectComposition 的 FP16 预乘透明 surface 承担最接近的传输角色,因此这是录屏可见性优先的视觉拟合, 不是对 hostCompositingSurface=dom-backdrop 的逐像素实现,也不保证所有录屏器都能捕获。

底层协议仍可由 PowerShell 或其他 Named Pipe 客户端验证:

GetState
GetDisplayState
GetConfig
GetFxConfig
GetHotkeyState
BeginHotkeyCapture
EndHotkeyCapture 42
RetryHotkeys
SetConfig {"generation":1,"path":"effects.globalScale","value":1.25}
SetConfig {"generation":1,"path":"input.trailOnlyWhilePressed","value":false}
SetConfig {"generation":1,"path":"input.samplingRateHz","value":30}
SetConfig {"generation":1,"path":"background.mode","value":"background-aware"}
SetConfig {"generation":1,"path":"background.mode","value":"recording-compatible"}
SetConfig {"generation":1,"path":"background.mode","value":"light-background"}
SetConfig {"generation":1,"path":"background.allowSystemBorder","value":false}
SetConfig {"generation":1,"path":"display.hdrEnabled","value":true}
SetConfig {"generation":1,"path":"performance.framePacing","value":"120"}
SetConfig {"generation":1,"path":"performance.framePacing","value":"unlimited"}
SetFxParam {"generation":1,"path":"effects.diskRadius","value":40}
SetFxParam {"generation":1,"path":"effects.diskLifetimeMs","value":250}
SetFxParams {"generation":1,"patch":{"effects.ringsCount":3,"effects.ringsLifetimeMs":700,"effects.ringsRadiusMin":60,"effects.ringsRadiusMax":90,"effects.ringsAngularVelocityMultiplier":12,"effects.ringsRotationDirection":-1}}
SetFxParams {"generation":1,"patch":{"effects.shardsClickCount":6,"effects.shardsClickLifetimeMinMs":500,"effects.shardsClickLifetimeMaxMs":650,"effects.shardsClickRadius":55,"effects.shardsClickSpeedMin":45,"effects.shardsClickSpeedMax":75,"effects.shardsSizeMin":14,"effects.shardsSizeMax":30}}
SetHotkeys 1 {"togglePause":{"modifiers":["ctrl"],"key":80},"toggleAlwaysOnTrail":null,"nextFxProfile":null,"shutdown":null}
SaveFxProfile 1 夜间 柔和
ApplyFxProfile 2 夜间 柔和
DeleteFxProfile 3 夜间 柔和
SetDisplayOverride {"generation":1,"displayKey":"displayconfig-v1-sha256:...","enabled":true,"hdrEnabled":false,"framePacing":"120"}
RemoveDisplayOverride {"generation":1,"displayKey":"displayconfig-v1-sha256:..."}
ResetFxConfig
ClearLogs
Pause
Resume
Shutdown

GetDisplayState 只接受同版本 Host 生成的严格 schema 4:未知、重复、缺失字段和旧 schema 都会被 Control Center 拒绝。它返回独立运行代次、配置/应用代次、全局拓扑状态、权威离线 override 列表,以及 每个会话实际应用的特效、HDR、颜色、cadence、输出状态和 Active-FX ROI 近 5 秒不可变工程快照;它不 修改配置,也不代表其中的实验能力已经完成硬件验收。schema 4 不提供 schema 3 兼容层。 SetConfig 仍接受完整的 schema 20 JSON 快照。GetFxConfigSetFxParam、原子批量的 SetFxParamsResetFxConfig 是本项目的原生 特效控制接口。GetFxConfig 返回平面的 EffectsConfig 字段,写入路径只接受唯一的 effects.* 命名空间,不接受 Web 别名或额外单位换算。FX 快照不包含 HDR、背景、输入、性能或系统字段;这些 产品设置只通过 GetConfig/SetConfig 管理。ResetFxConfig 只恢复 effects,保留背景、HDR、输入和系统设置; Control Center 的“重置默认”使用完整 schema 恢复其他持久化设置,同时保留 Host 已保存的整组快捷键。 路径补丁只允许配置库声明的产品字段,代次不匹配会返回 generation_conflict;渲染配置在下一帧应用, 当前暂停或运行状态不因重置而变化。

GetStateproductVersion 是 Host/Control Center 设置兼容门,不是配置 schema 版本。只有它与 Control Center 自身版本完全一致时,控制面才允许修改设置;缺失、非法或不匹配都 fail-closed。 Host 生命周期入口不受该门限制。0.2.10 将主配置升级为 schema 20,增加默认全未绑定的 hotkeys。 显示器 override、data 目录和 effects-only fx-profiles 无需重建。

全局快捷键

“快捷键”页支持直接录制、清除、整组保存和重试注册。四项动作是暂停/恢复、切换常驻拖尾、 下一个特效预设和退出 Host。暂停仅影响运行时;拖尾和预设动作按现有配置流程保存,预设不包含快捷键。

执行仅使用 RegisterHotKey / WM_HOTKEY,注册统一附加 MOD_NOREPEAT。支持单个非修饰主键及 Ctrl/Alt/Shift/Win 加一个主键,不区分左右修饰键,长按不重复。不支持多普通键、宏或仅修饰键; F12 禁止绑定,Win 组合不保证可用。 注册可能影响其他应用的原按键行为,不提供输入透传。重复组合被拒绝,ACtrl+A 则可分别绑定。

录制期间保留旧注册但不执行动作;候选只进入草稿。失焦、取消、30 秒超时或 5 秒失联后结束录制。 其他软件或系统占用的组合可能无法录到,请换一组。保存按当前 Host generation 执行:保留旧注册并先 申请全部新增组合,随后原子写入完整配置,最后启用新绑定并释放不再使用的旧注册。注册、代次冲突或 写盘失败均不改变旧绑定;配置已经写入但激活结果无法确认,或旧注册清理失败时,页面会确认权威配置并 明确提示重启 Host。启动注册失败不会阻止特效运行,“重试注册”只重试已保存绑定,并汇总已保存、已注册 和失败数量。

支持报告记录 Hotkeys.StateScope=startup,以及 Host 启动时的注册掩码、四项动作的注册结果和 Win32 错误、清理错误;它不是导出瞬间的实时状态。Exit.PollingFallback=disabled 明确表明旧固定 F12 轮询 退出路径已删除。

新增 IPC:SetHotkeys <generation> <hotkeys-json>GetHotkeyState [capture-token]RetryHotkeysBeginHotkeyCaptureEndHotkeyCapture <capture-token>GetHotkeyState 返回标准 Host 状态加完整的 快捷键状态组;绑定通过 hotkeysJson 字符串携带,hotkeyRegisteredMask 的低四位依次对应上述四个动作, hotkeyError0hotkeyError3 为 Win32 注册错误码。仅匹配的非零 token 查询才会续期录制。

特效 Profile 同样由 Host 持有,内置且不可删除的四项是“Unity 原版”“轻量”“纯点击”和“纯拖尾”。 GetState 通过 fxProfileCatalog 返回内置/自定义目录,通过 activeFxProfile 返回当前特效与某一 Profile 完全匹配的名称,并用 fxProfileWarning 报告启动时被跳过的损坏、冲突或不可读文件;没有精确 匹配时显示“自定义”。SaveFxProfileApplyFxProfileDeleteFxProfile 的负载均以当前 generation 开头,名称可以包含空格;过期请求返回 generation_conflict。保存使用同目录临时文件、flush 和替换,应用先通过主配置的原子写入提交候选 effects,删除以单个自定义 Profile 文件的移除作为提交点。只有操作成功后 Host 才更新内存状态;三种 操作都会把用于并发冲突检测的控制 generation 增加一次,但只有应用会推进独立的配置 generation。 纯目录的保存/删除不会触发渲染与捕获状态的无意义重应用,失败也不会发布半更新的目录或配置。 为保证 activeFxProfile 身份稳定,Host 会拒绝与其他内置或自定义 Profile 完全相同的 effects 快照。

Profile 是严格的 effects-only 快照:保存和应用只涉及 effects,明确不包含也不改变 backgrounddisplayinputperformancesystem。因此实验性 Active-FX ROI 的 performance.activeFxRoiEnabled 也不属于 Profile;切换 Profile 不会顺带打开、关闭或覆盖 ROI。

诊断日志按单文件 8 MiB 轮转,最多保留 .log.1.log.2.log.3 三个备份,总预算约 32 MiBClearLogs 会清理当前文件及遗留备份,清理动作本身会留下新的结构化结果记录;日志清理失败不会停止 Host 或修改配置。用户反馈时只需提交当前日志和仍存在的轮转文件,不需要运行额外诊断包。

packed_fx_textures 测试逐张解压 raw LZ4 Block,并锁定 RGBA8 texel 的尺寸、行距和 SHA-256。 生成器是仅供维护者使用的开发工具;只有在更新 Unity 真值快照时才需要运行,输入 PNG、Node.js 和 Unity 工程都不是构建产物或运行时依赖:

node tools\generate-packed-fx-textures.mjs `
  --project "D:\path\to\UnityProject"

开发说明

本项目主要通过 AI 生成和迭代完成(绝无手写代码),并经过实际运行测试、参数调校和效果校准。项目目标是尽可能还原《蔚蓝档案》风格的点击特效与拖尾轨迹。

许可证

GNU GPL v2 许可证。