clsty
1
起因是我关注到 GitHub - refractify/myopic_defocus: Myopic Defocus Browser Extension. 这个 Chrome 插件。
进而是 Pilot study: simulating myopic chromatic aberration on a computer screen induces progressive choroidal thickening in myopes | Scandinavian Journal of Optometry and Visual Science 这篇论文(doi:10.15626/sjovs.v17i2.4232)。(更新:此论文的 markdown 版本在 23 楼)
由此论文可知,对于近视人群,将屏幕中 RGB 三通道中的 G 轻微模糊、B 更加模糊,可以抑制甚至逆转眼轴长度增加,从而减轻近视程度。上面的 Chrome 插件就是对此原理的一个实现。
这个原理看上去很简单,我打算在 Plasma Wayland 下全局实现这个效果,为此我新建了
并且让 GitHub Copilot 来 Vibe Coding(因为我不太会编程,没办法亲自动手)。
但无论怎么尝试,这个 Kwin 插件始终未能生效,也即无论怎么更改配置都看不出有什么变化。
我在想,是不是从根本上,Kwin 插件这个思路就是错误的,比如或许有更底层的方法来实现目标(比如直接从某种缓冲区读数据来处理,似乎 sunshine 就是这样获取屏幕数据的)。
P.S. 刚才搜到 GitHub - zcf0508/myopic_defocus: Myopic Defocus App 这个类似项目(仅 Windows),看自述文档,似乎也是 Vibe Coding 出来的。
1 个赞
clsty
3
这个项目在做 Vibe Coding 的时候,首先我以聊天形式问了 AI 怎么实现比较合适,AI 说可以用 Kwin Effect 插件实现。
所以之后我告诉 Copilot 我想要的是 Kwin Effect 插件(类似于 GitHub - a-parhom/LightlyShaders: Rounded window corners and outline effect for KWin. )。具体可以参见 clsty/waymca 的前 4 个 Pull Request。
不过实际上只要能达成“让我的屏幕的RGB通道中的G通道和B通道分别进行高斯模糊,并可以配置模糊参数”(我的桌面是 KDE Plasma Wayland),就不局限于具体的手段。
clsty
4
又搜到 myopic_defocus 的另一实现(Typora 插件)
我仍然找不到 Linux(wayland)上能用的实现,也 vibe coding 不出来。
不过,希望能有更多近视患者用上已有的实现,这样此需求也会被重视起来。
虽然是我推荐的,但我自己还没用上(我的浏览器是 Firefox,而且我常用的 GUI 应用远不止浏览器),只能羡慕着了。
1 个赞
希望哪位大神能实现这个,这样我这个100度的近视有希望逆转。
1 个赞
yibie
6
首先,你能否将这个原理详细地解释出来。另外,你看好的那个帖子,它只能用在 macOS 上,无法用于 Linux。
如果你想真的让别人实现,你起码力所能及地降低别人参与的成本。
你有没有试过用kwin script而不是c++实现这个功能呢?
uniform float2 resolution;
uniform float2 offset;
// Gaussian kernel (small for performance)
float3 gaussian(float x) {
float sigma = 2.0;
return exp(-0.5 * (x * x) / (sigma * sigma)) / (sigma * sqrt(2.0 * 3.14159));
}
// Apply Gaussian blur to G and B only
float4 fragment(in float2 pos) {
float2 uv = pos / resolution;
float4 color = texture2D(sampler2D, uv);
// Only blur G and B channels
float g = color.g;
float b = color.b;
// Simple 5x5 Gaussian blur (approximate)
float4 sum = float4(0.0);
float weightSum = 0.0;
for (int i = -2; i <= 2; i++) {
for (int j = -2; j <= 2; j++) {
float2 offset = float2(i, j);
float w = gaussian(offset.x) * gaussian(offset.y);
sum += texture2D(sampler2D, uv + offset * 0.01) * w;
weightSum += w;
}
}
// Reconstruct: R unchanged, G and B blurred
float4 blurred = color;
blurred.g = sum.g / weightSum;
blurred.b = sum.b / weightSum;
return blurred;
}
1 个赞
付费买了这个软件的Windows版本,可以全局开启。
但是我在两台电脑测试了,旧版速度快不过24H2开始不被支持,新版速度慢点但是换了API,不过效果和旧版不太一样。chrome插件的那种泛红效果比较接近旧版。
clsty
9
感谢你的建议。
我一开始已经说了原理:
它本身是非常简单的,所以我不知道怎么样才能更详细地解释。
当然,既然你这样说了,我可以尝试一下:
毛玻璃特效,或者说高斯模糊,大家都知道吧?但这是对 RGB 三个通道一起施加的。
这个护眼方案所需要的就是把这种模糊应用到全屏(而不只是透明背景),不同之处是要将三个通道拆分,其中 R 通道保持原样(不模糊),G 通道加一点点模糊,B 通道加更多一点模糊。
你可能误解了我的意思。我引用那个贴子只是因为别人作为 Chrome 用户已经体验到了(我是 Firefox 用户,目前不打算改用 Chrome 的),而且他反馈说效果还不错(我自己并没有亲自体验过这种效果),所以我有点羡慕。这跟 MacOS 没有关系。
你说得对,只是我目前想不到还能做什么。如果还有别的建议都欢迎提出。
2 个赞
clsty
10
在其中一个 PR 里,我记得 Copilot 就是用的 kwin script,但一直没有生效。于是我把这个 PR 发给 AI 问了一下为什么不能生效,AI 说必须用 c++ 才行。
当然,AI 说得未必是对的。谢谢你提供的代码,我待会试试。
clsty
12
好的,也就是说具体需要什么程度的模糊对吧?这点我确实没有说明到,不过具体的模糊程度应当是一个可调整的参数(kwin 插件是支持提供用户配置界面的),而不是写死的,所以这个模糊的程度可能不需要说明?
yibie
13
你可否把这个当成写产品文档。没有具体的参数,怎么实现?如果你觉得这很麻烦。我建议还是自己努力问问 AI。
clsty
14
以 LightlyShaders 为例,这是它的配置界面。
可以看到 Corner size、Shadow offset 等等参数都不是写死的。
对于高斯模糊的程度也是一样,它应当是一个可以配置的值(G 通道、B 通道分别配置),因为每个用户的体质、显示屏的硬件参数都不一样,所以这个模糊程度也不应该是硬编码的。
不过,你可能是指,具体有哪些参数(而不是参数的值)?那样的话也就是要涉及到具体的高斯模糊算法了。我自己不会,所以我问了一下 AI(P.S. 问了之后又感觉有点多余,我自己问和别人问都是一样的),得到的回复是这样的:
折叠展开
高斯模糊是一种常用于图像处理的平滑滤波算法,可以去除噪点或者实现柔和的模糊效果。它利用高斯函数(正态分布)来给每个像素及其邻域加权平均,实现模糊。
高斯模糊的算法原理
-
数学表达式
高斯函数(1D):
G(x) = \frac{1}{\sqrt{2\pi\sigma^2}} e^{-\frac{x^2}{2\sigma^2}}
高斯函数(2D):
G(x, y) = \frac{1}{2\pi\sigma^2} e^{-\frac{x^2 + y^2}{2\sigma^2}}
其中 \sigma 是标准差,决定了模糊的“强度”和“范围”。
-
实现步骤
- 生成一个高斯核(滤波器矩阵),元素由高斯函数决定,尺寸通常为 (2r+1)\times(2r+1),r 为半径。
- 将核与图像进行卷积。每个像素的新值为邻近像素的加权平均,权重取自高斯核。
-
优化技巧
- 分离卷积:2D 高斯卷积可以分解为两个 1D 卷积(先横向再纵向),大大加快运算速度。
- 利用 GPU 着色器(如 KWin 中常见)实现实时模糊。
可自定义的参数
-
标准差 \sigma(或称模糊强度/半径)
- 决定模糊的“散开”程度,值越大,模糊越明显。常见的用户界面展示为“模糊强度”滑块。
-
核尺寸(Kernel Size)或半径(Radius)
- 实际用于卷积的邻域大小。经常与 \sigma 相关。
-
步进或精度(可选)
- 控制采样数量,用于优化性能与效果。常用于着色器实现时采样点多少。
-
混合强度/不透明度(可选)
-
颜色通道选择(可选)
用户界面建议的常见参数
- 模糊强度(滑块,对应 \sigma )
- 核尺寸/半径(滑块或选择器)
- 混合强度(可选)
- 预设风格(如:轻度、中度、强烈)
KWin 插件开发相关建议
- 使用 OpenGL/GLSL 着色器实现高效实时高斯模糊。
- 提供 QML 配置界面,暴露上述参数,允许用户动态调整(可调用 DBus 方法传参)。
- 支持动态重载着色器以无缝升级用户体验。
clsty
16
原论文没有提到散光,从生理机制也即由色散效应给出的信号刺激脉络膜(choroid)增厚并使得视轴长度(axial length)缩短(ok 镜、阿托品、离焦镜等也是这种机制)上来看,应该也与散光没有直接关系。
clsty
17
你用的是 Chrome 插件同一家(refractify.io)的那个闭源版本的 Windows 的实现对吧?
对于 Windows,我在一楼还贴了一个第三方开源实现也可以试试。
clsty
18
你给的代码我不知道怎么用在 Plasma wayland 上,问了 AI 似乎是 GLSL 着色器代码,需要改 Kwin 源码然后重新编译 Kwin……还是挺花时间的,也未必能成功。(在 Debian 下构建很不方便,因为很多包都缺或者太老,除非用 testing 可能好一点,但那就偏离我改用 Debian 追求稳定性的目的了)
我在想,如果我不用 Debian 13,而是去用支持 Hyprland(或 Niri)的发行版,会不会简单一些,毕竟 Hyprland 的 Shader 插件 我曾经用过,它支持包括灰阶效果等,是全屏覆盖的效果。从 README 来看,似乎也支持自定义 glsl 着色器,例如运行这种命令即可生效:
hyprshade on ~/.config/hypr/shaders/blue-light-filter.glsl
而 Plasma 这边我一直找不到全屏效果的 Kwin 插件(那个 LightlyShaders 只针对窗口边框)——总之,有空我换个 Fedora 或者 NixOS 吧。我受不了 Arch 那种 mono repo 以及过快的更新频率(已经主力用了两年),Debian 又没办法用 Hyprland 或者 Niri。
最开始就用过这个实现,也许是python的性能问题,帧数下降可以体感出来,所以买了付费软件。
1 个赞
伙计们,加油!这里大佬多,相信一定能整出来。为表示对这个工作的支持,我愿10杯咖啡以表示感谢。
2 个赞