moire: make bokeh its own pattern rather than a checkbox

c3df760 · Gabriel Morell · 2026-09-29 21:06

13 files +15 -33

Files changed

modified README.md
+3 −5
@@ -54,7 +54,9 @@ adds to its size.
54 54 `plasma-wallpaper-neiam-moire` is a Plasma wallpaper plugin ("neiam
55 55 moire" under *Wallpaper type*, for the desktop or the lock screen)
56 56 that draws the moire live, with a halftone field, both, or fading
57 −between the two. Everything drifts slowly and never visibly repeats.
57 +between the two, or bokeh: soft out-of-focus discs in the accent and
58 +primary colours, drifting upward and fading in and out as they rise.
59 +Everything drifts slowly and never visibly repeats.
58 60
59 61 Its colours come from the waxx themes (dark, light, her, afterdark,
60 62 forest, sky, clays, stones, blueprint): the ground is `base-100`
@@ -65,10 +67,6 @@ latitude and longitude. Between phases it blends by the sun's
65 67 elevation, turning the hue so the transitions pass through the purples
66 68 of a real twilight rather than grey.
67 69
68 −Bokeh (off by default) adds soft out-of-focus discs in the accent and
69 −primary colours, drifting upward behind the pattern and fading in and
70 −out as they rise.
71 −
72 70 A checkbox writes "NEIAM" in the bottom right corner, in the theme's
73 71 accent colour, in B612 Mono Bold at 12% of the screen height; the package pulls
74 72 in the font (`fonts-b612` / `firstyear-b612-fonts`).
modified moire/shaders/field.frag
+2 −4
@@ -58,8 +58,7 @@ float hash(float n)
58 58 return fract(sin(n * 127.1 + 311.7) * 43758.5453);
59 59 }
60 60
61 −// Out-of-focus lights drifting upward behind the pattern, as if the
62 −// moire were in focus in front of them. Each disc moves at a whole
61 +// Out-of-focus lights drifting upward. Each disc moves at a whole
63 62 // multiple of drift, so when drift wraps from 1 back to 0 every disc
64 63 // is exactly where it started; each fades in rising from the bottom
65 64 // and out before the top, so none ever appears or vanishes abruptly.
@@ -101,11 +100,10 @@ void main()
101 100 float v = smoothstep(0.35, 1.25, length(p - centre));
102 101 vec3 colour = mix(base.rgb, deep.rgb, v);
103 102
104 − // Bokeh sits behind everything else: it is the out-of-focus scene.
105 103 if (bokeh > 0.0) {
106 104 float tint;
107 105 float light = bokehLight(p, size.x * px, px, tint);
108 − colour = mix(colour, mix(ink.rgb, tone.rgb, tint), light * 0.14 * bokeh);
106 + colour = mix(colour, mix(ink.rgb, tone.rgb, tint), light * 0.3 * bokeh);
109 107 }
110 108
111 109 // Halftone: dots on a rotated grid, each sized by the fade and a
modified moire/theme/contents/config/main.xml
+1 −5
@@ -7,7 +7,7 @@
7 7
8 8 <group name="General">
9 9 <entry name="Pattern" type="String">
10 − <label>moire, halftone, both, or alternate</label>
10 + <label>moire, halftone, both, alternate, or bokeh</label>
11 11 <default>both</default>
12 12 </entry>
13 13 <entry name="Speed" type="Double">
@@ -18,10 +18,6 @@
18 18 <label>Frames per second while animating</label>
19 19 <default>30</default>
20 20 </entry>
21 − <entry name="Bokeh" type="Bool">
22 − <label>Soft out-of-focus lights drifting up behind the pattern</label>
23 − <default>false</default>
24 − </entry>
25 21 <entry name="Wordmark" type="Bool">
26 22 <label>Write NEIAM in the bottom right corner</label>
27 23 <default>false</default>
modified moire/theme/contents/ui/Field.qml
+8 −10
@@ -10,16 +10,14 @@ import QtQuick 2.15
10 10 Item {
11 11 id: field
12 12
13 − // "moire", "halftone", "both", or "alternate" (fading between the
14 − // two every few minutes).
13 + // "moire", "halftone", "both" (moire over halftone), "alternate"
14 + // (fading between those two every few minutes), or "bokeh".
15 15 property string pattern: "both"
16 16 // Multiplies how fast everything drifts; 0 holds the picture still.
17 17 property real speed: 1
18 18 property int frameRate: 30
19 19 // "NEIAM" in the bottom right, in the ink colour.
20 20 property bool wordmark: false
21 − // Soft out-of-focus discs drifting up behind the pattern.
22 − property bool bokeh: false
23 21
24 22 property color base: "#661e1e"
25 23 property color deep: "#470005"
@@ -69,17 +67,17 @@ Item {
69 67 // One bokeh cycle is ten minutes; the fastest disc climbs the
70 68 // screen three times in it.
71 69 property real drift: (field.clock / 600) % 1
72 − property real bokeh: field.bokeh ? 1 : 0
73 − Behavior on bokeh { NumberAnimation { duration: 1500 } }
74 70
75 71 // Amounts ease so a pattern change fades rather than cuts.
76 72 readonly property real alternate: 0.5 + 0.5 * field.sweep(360, 0)
77 − property real moire: field.pattern === "halftone" ? 0
78 − : field.pattern === "alternate" ? alternate : 1
79 − property real halftone: field.pattern === "moire" ? 0
80 − : field.pattern === "alternate" ? 1 - alternate : 1
73 + property real moire: field.pattern === "alternate" ? alternate
74 + : field.pattern === "moire" || field.pattern === "both" ? 1 : 0
75 + property real halftone: field.pattern === "alternate" ? 1 - alternate
76 + : field.pattern === "halftone" || field.pattern === "both" ? 1 : 0
77 + property real bokeh: field.pattern === "bokeh" ? 1 : 0
81 78 Behavior on moire { enabled: field.pattern !== "alternate"; NumberAnimation { duration: 1500 } }
82 79 Behavior on halftone { enabled: field.pattern !== "alternate"; NumberAnimation { duration: 1500 } }
80 + Behavior on bokeh { NumberAnimation { duration: 1500 } }
83 81
84 82 property color base: field.base
85 83 property color deep: field.deep
modified moire/theme/contents/ui/config.qml
+1 −8
@@ -15,7 +15,6 @@ Kirigami.FormLayout {
15 15 property double cfg_Speed
16 16 property int cfg_FrameRate
17 17 property bool cfg_Wordmark
18 − property bool cfg_Bokeh
19 18 property string cfg_ThemeMode
20 19 property string cfg_Theme
21 20 property string cfg_NightTheme
@@ -33,6 +32,7 @@ Kirigami.FormLayout {
33 32 { value: "moire", text: "Moire" },
34 33 { value: "halftone", text: "Halftone" },
35 34 { value: "alternate", text: "Fade between moire and halftone" },
35 + { value: "bokeh", text: "Bokeh" },
36 36 ]
37 37
38 38 component ThemeBox: QQC2.ComboBox {
@@ -86,13 +86,6 @@ Kirigami.FormLayout {
86 86 enabled: root.cfg_Speed > 0
87 87 }
88 88
89 − QQC2.CheckBox {
90 − Kirigami.FormData.label: "Bokeh:"
91 − text: "Drifting out-of-focus lights"
92 − checked: root.cfg_Bokeh
93 − onToggled: root.cfg_Bokeh = checked
94 − }
95 −
96 89 QQC2.CheckBox {
97 90 Kirigami.FormData.label: "Wordmark:"
98 91 text: "Write NEIAM in the corner"
modified ?
+0 −0

Binary file — not rendered.

modified moire/theme/contents/ui/main.qml
+0 −1
@@ -32,7 +32,6 @@ WallpaperItem {
32 32 speed: root.cfg.Speed
33 33 frameRate: root.cfg.FrameRate
34 34 wordmark: root.cfg.Wordmark
35 − bokeh: root.cfg.Bokeh
36 35 base: root.scheme.base
37 36 deep: root.scheme.deep
38 37 ink: root.scheme.ink

Parents: ca16122