per-pixel wave reveal mask for lock screen overlay layers

This commit is contained in:
Damocles 2026-04-18 11:35:51 +02:00
parent e4b257d760
commit e2f8accbc1
3 changed files with 59 additions and 33 deletions

View file

@ -27,10 +27,13 @@ stdenvNoCC.mkDerivation {
mkdir -p $out/share/nova-shell
cp -r shell/shell.qml shell/modules shell/services shell/applets shell/lock shell/assets $out/share/nova-shell/
# Compile fragment shader to Qt RHI format
# Compile fragment shaders to Qt RHI format
qsb --qt6 \
-o $out/share/nova-shell/modules/hex_wave.frag.qsb \
shell/modules/hex_wave.frag
qsb --qt6 \
-o $out/share/nova-shell/modules/reveal_mask.frag.qsb \
shell/modules/reveal_mask.frag
mkdir -p $out/bin
makeWrapper ${lib.getExe quickshell} $out/bin/nova-shell \

View file

@ -13,9 +13,7 @@ WlSessionLockSurface {
color: S.Theme.base00
// Wave progress drives blur/dim/hex overlay reveal
property real _unlockFade: 1
readonly property real _waveProgress: (root.width > 0 ? Math.max(0, Math.min(1, _hexWave.wavePhase / root.width)) : 0) * _unlockFade
// Clear desktop screenshot - visible immediately
ScreencopyView {
@ -25,35 +23,46 @@ WlSessionLockSurface {
opacity: _unlockFade
}
// Blurred screenshot - fades in as wave passes
ScreencopyView {
// Overlay group: blur + dim + hexes, revealed per-pixel by wave position
Item {
anchors.fill: parent
captureSource: root.screen
visible: S.Modules.lock.screenshot ?? true
opacity: root._waveProgress
opacity: _unlockFade
layer.enabled: true
layer.effect: MultiEffect {
autoPaddingEnabled: false
blurEnabled: true
blur: 1
blurMax: 64
layer.effect: ShaderEffect {
property real uPhase: _hexWave.wavePhase
property real uWidth: root.width
fragmentShader: Quickshell.shellPath("modules/reveal_mask.frag.qsb")
}
}
// Dim overlay - fades in with wave
Rectangle {
anchors.fill: parent
color: Qt.rgba(S.Theme.base00.r, S.Theme.base00.g, S.Theme.base00.b, 0.4)
opacity: root._waveProgress
}
// Blurred screenshot
ScreencopyView {
anchors.fill: parent
captureSource: root.screen
visible: S.Modules.lock.screenshot ?? true
// Hex wave - fades in with wave progress
C.HexWaveBackground {
id: _hexWave
anchors.fill: parent
running: root.lock.secure
opacity: root._waveProgress * 0.4
layer.enabled: true
layer.effect: MultiEffect {
autoPaddingEnabled: false
blurEnabled: true
blur: 1
blurMax: 64
}
}
// Dim overlay
Rectangle {
anchors.fill: parent
color: Qt.rgba(S.Theme.base00.r, S.Theme.base00.g, S.Theme.base00.b, 0.4)
}
// Hex wave
C.HexWaveBackground {
id: _hexWave
anchors.fill: parent
running: root.lock.secure
opacity: 0.4
}
}
// Keyboard input via TextInput - engages Qt's full input pipeline including
@ -242,13 +251,6 @@ WlSessionLockSurface {
duration: 300
easing.type: Easing.InCubic
}
NumberAnimation {
target: _hexWave
property: "opacity"
to: 0
duration: 300
easing.type: Easing.InCubic
}
}
PropertyAction {

View file

@ -0,0 +1,21 @@
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float uPhase;
float uWidth;
};
layout(binding = 1) uniform sampler2D source;
void main() {
vec4 tex = texture(source, qt_TexCoord0);
float x = qt_TexCoord0.x * uWidth;
// Soft reveal edge: fully visible 200px behind wave, fades out 50px ahead
float mask = 1.0 - smoothstep(uPhase - 200.0, uPhase + 50.0, x);
fragColor = tex * mask * qt_Opacity;
}