diff --git a/kwin/build.sh b/kwin/build.sh
index 20aa12b..805394b 100755
--- a/kwin/build.sh
+++ b/kwin/build.sh
@@ -109,4 +109,5 @@ generate "energize-a" "Energize A" "Beam your windows away"
generate "energize-b" "Energize B" "Using different transporter technology results in an alternative visual effect"
generate "hexagon" "Hexagon" "With glowing lines and hexagon-shaped tiles, this effect looks very sci-fi"
generate "tv" "TV Effect" "Make windows close like turning off a TV"
+generate "wisps" "Wisps" "Let your windows be carried away to the realm of dreams by these little fairies"
# generate "fire" "Fire" "Make windows burn"
\ No newline at end of file
diff --git a/kwin/wisps/config.ui b/kwin/wisps/config.ui
new file mode 100755
index 0000000..c0670e0
--- /dev/null
+++ b/kwin/wisps/config.ui
@@ -0,0 +1,84 @@
+
+
+ BMWConfigForm
+
+
+
+ 0
+ 0
+ 562
+ 365
+
+
+
+ -
+
+
+ 0.100000000000000
+
+
+ 10.000000000000000
+
+
+
+ -
+
+
+ milliseconds
+
+
+ 100
+
+
+ 9999
+
+
+ 100
+
+
+
+ -
+
+
+ Color:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Duration:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Scale:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+
+
+
+
+ KColorButton
+ QPushButton
+
+
+
+
+
+
\ No newline at end of file
diff --git a/kwin/wisps/main.xml b/kwin/wisps/main.xml
new file mode 100755
index 0000000..893f5de
--- /dev/null
+++ b/kwin/wisps/main.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ 1500
+
+
+ 1
+
+
+ #ff64c8
+
+
+
\ No newline at end of file
diff --git a/kwin/wisps/onAnimationBegin.js b/kwin/wisps/onAnimationBegin.js
new file mode 100644
index 0000000..12be257
--- /dev/null
+++ b/kwin/wisps/onAnimationBegin.js
@@ -0,0 +1,4 @@
+// This part is automatically included in the effect's source during the build process.
+// The code below is called whenever a window is closed or opened.
+
+effect.setUniform(this.shader, 'uSeed', [Math.random(), Math.random()]);
diff --git a/kwin/wisps/onSettingsChanged.js b/kwin/wisps/onSettingsChanged.js
new file mode 100644
index 0000000..6a8173e
--- /dev/null
+++ b/kwin/wisps/onSettingsChanged.js
@@ -0,0 +1,6 @@
+// This part is automatically included in the effect's source during the build process.
+// The code below is called whenever the user changes something in the configuration of
+// the effect.
+
+effect.setUniform(this.shader, 'uScale', effect.readConfig('Scale', 1.0));
+effect.setUniform(this.shader, 'uColor', effect.readConfig('Color', 'white'));
diff --git a/resources/shaders/wisps.frag b/resources/shaders/wisps.frag
index 08a3c05..927f35a 100644
--- a/resources/shaders/wisps.frag
+++ b/resources/shaders/wisps.frag
@@ -14,7 +14,7 @@
// The content from common.glsl is automatically prepended to each shader effect.
uniform vec2 uSeed;
-uniform vec3 uColor;
+uniform vec4 uColor;
uniform float uScale;
const float WISPS_RADIUS = 20.0;
@@ -98,7 +98,7 @@ void main() {
oColor.a *= windowMask * mask;
// Add the wisps.
- vec4 wispColor = wisps * vec4(uColor, min(wispsIn, 1.0 - wispsOut) * mask);
+ vec4 wispColor = wisps * vec4(uColor.rgb, min(wispsIn, 1.0 - wispsOut) * mask);
oColor = alphaOver(oColor, wispColor);
// These are pretty useful for understanding how this works.
diff --git a/src/Wisps.js b/src/Wisps.js
index bb6919e..69f09e6 100644
--- a/src/Wisps.js
+++ b/src/Wisps.js
@@ -58,7 +58,7 @@ var Wisps = class {
// clang-format off
shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]);
- shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]);
+ shader.set_uniform_float(shader._uColor, 4, [c.red / 255, c.green / 255, c.blue / 255, 1.0]);
shader.set_uniform_float(shader._uScale, 1, [settings.get_double('wisps-scale')]);
// clang-format on
});