diff --git a/resources/scene.jpg b/resources/scene.jpg new file mode 100644 index 0000000..93e1865 Binary files /dev/null and b/resources/scene.jpg differ diff --git a/resources/test.png b/resources/test.png new file mode 100644 index 0000000..2c8e844 Binary files /dev/null and b/resources/test.png differ diff --git a/shaders/liquid-glass.frag b/shaders/liquid-glass.frag new file mode 100644 index 0000000..3faaa4f --- /dev/null +++ b/shaders/liquid-glass.frag @@ -0,0 +1,64 @@ +#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 time; + float warpStrength; + float flowSpeed; + float scale; +} ubuf; + +layout(binding = 1) uniform sampler2D source; + +// Smooth noise function for organic liquid movement +float noise(vec2 p) { + return sin(p.x * 1.5) * sin(p.y * 1.5); +} + +// Fractal noise for more complex patterns +float fbm(vec2 p) { + float value = 0.0; + float amplitude = 0.5; + + for(int i = 0; i < 4; i++) { + value += amplitude * noise(p); + p *= 2.0; + amplitude *= 0.5; + } + return value; +} + +void main() { + vec2 uv = qt_TexCoord0; + + // Create flowing liquid-like distortion + vec2 flowDir1 = vec2( + fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed), + fbm(uv * ubuf.scale + ubuf.time * ubuf.flowSpeed + 100.0) + ); + + vec2 flowDir2 = vec2( + fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 200.0), + fbm(uv * ubuf.scale * 0.7 - ubuf.time * ubuf.flowSpeed * 0.8 + 300.0) + ); + + // Combine flows for more organic movement + vec2 finalFlow = (flowDir1 + flowDir2 * 0.5) * ubuf.warpStrength * 0.01; + + // Apply subtle chromatic aberration like Apple's effect + float aberration = length(finalFlow) * 0.5; + + vec2 distortedUV = uv + finalFlow; + + // Sample with slight chromatic separation + float r = texture(source, distortedUV + vec2(aberration, 0.0)).r; + float g = texture(source, distortedUV).g; + float b = texture(source, distortedUV - vec2(aberration, 0.0)).b; + + fragColor = vec4(r, g, b, 1.0) * ubuf.qt_Opacity; +} + diff --git a/shaders/liquid-glass.frag.qsb b/shaders/liquid-glass.frag.qsb new file mode 100644 index 0000000..805b78b Binary files /dev/null and b/shaders/liquid-glass.frag.qsb differ diff --git a/shell.qml b/shell.qml new file mode 100644 index 0000000..e04bcf4 --- /dev/null +++ b/shell.qml @@ -0,0 +1,163 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Quickshell +import Quickshell.Widgets +import Qt5Compat.GraphicalEffects + +ShellRoot { + FloatingWindow { + color: "grey" + implicitWidth: 840 + implicitHeight: 845 + + maximumSize { + width: 840 + height: 845 + } + + minimumSize { + width: 840 + height: 845 + } + + ColumnLayout { + // anchors.fill: parent + anchors { + centerIn: parent + } + + Item { + Layout.preferredWidth: 600 + Layout.preferredHeight: 600 + + Image { + id: backgroundContent + fillMode: Image.PreserveAspectCrop + source: "root:resources/scene.jpg" + anchors.fill: parent + } + + ClippingRectangle { + id: glassContainer + color: "transparent" + radius: 20 + anchors.centerIn: parent + width: 400 + height: 300 + + // Blur + ShaderEffectSource { + id: blurredBackground + anchors.fill: parent + sourceItem: backgroundContent + sourceRect: Qt.rect(glassContainer.x, glassContainer.y, glassContainer.width, glassContainer.height) + hideSource: false + live: true + } + + FastBlur { + id: backgroundBlur + anchors.fill: parent + source: blurredBackground + radius: 32 + transparentBorder: true + } + + // Liquid glass shader warp + ShaderEffect { + anchors.fill: parent + fragmentShader: "root:shaders/liquid-glass.frag.qsb" + + property real time: timeSlider.value + property real warpStrength: warpSlider.value + property real flowSpeed: speedSlider.value + property real scale: 3.0 + + property variant source: ShaderEffectSource { + sourceItem: backgroundBlur + hideSource: false + live: true + } + } + + // Glass overlay + Rectangle { + anchors.fill: parent + color: "transparent" + border.width: 1 + border.color: Qt.rgba(1, 1, 1, 0.2) + radius: 20 + + Rectangle { + anchors.fill: parent + anchors.margins: 1 + radius: parent.radius - 1 + gradient: Gradient { + GradientStop { + position: 0.0 + color: Qt.rgba(1, 1, 1, 0.1) + } + GradientStop { + position: 0.3 + color: Qt.rgba(1, 1, 1, 0.05) + } + GradientStop { + position: 1.0 + color: Qt.rgba(0, 0, 0, 0.05) + } + } + } + } + } + } + + RowLayout { + Text { + text: "Time:" + } + + Slider { + id: timeSlider + from: 0 + to: Math.PI * 2 + + Layout.fillWidth: true + Layout.preferredHeight: 30 + } + } + + RowLayout { + Text { + text: "Warp Strength:" + } + + Slider { + id: warpSlider + from: 0 + to: 10 + + Layout.fillWidth: true + Layout.preferredHeight: 30 + } + } + + RowLayout { + Text { + text: "Flow Speed:" + } + + Slider { + id: speedSlider + from: 0 + to: 1 + + Layout.fillWidth: true + Layout.preferredHeight: 30 + } + } + } + } +}