From 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 Mon Sep 17 00:00:00 2001 From: AlexanderCurl Date: Sat, 18 Apr 2026 17:46:06 +0100 Subject: Replaced file structures for themes in the correct format --- .../quickshell/Shaders/frag/ripple.frag | 61 ++++++ .../quickshell/Shaders/frag/wp_disc.frag | 126 +++++++++++++ .../quickshell/Shaders/frag/wp_fade.frag | 91 +++++++++ .../quickshell/Shaders/frag/wp_iris_bloom.frag | 119 ++++++++++++ .../quickshell/Shaders/frag/wp_pixelate.frag | 125 +++++++++++++ .../quickshell/Shaders/frag/wp_portal.frag | 124 +++++++++++++ .../quickshell/Shaders/frag/wp_stripes.frag | 205 +++++++++++++++++++++ .../quickshell/Shaders/frag/wp_wipe.frag | 129 +++++++++++++ 8 files changed, 980 insertions(+) create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/ripple.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_disc.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_fade.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_iris_bloom.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_pixelate.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_portal.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_stripes.frag create mode 100644 raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_wipe.frag (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag') diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/ripple.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/ripple.frag new file mode 100644 index 0000000..2552bb6 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/ripple.frag @@ -0,0 +1,61 @@ +#version 450 + +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 widthPx; + float heightPx; + float cornerRadiusPx; + float rippleCenterX; + float rippleCenterY; + float rippleRadius; + float rippleOpacity; + float offsetX; + float offsetY; + float parentWidth; + float parentHeight; + vec4 rippleCol; +} ubuf; + +float sdRoundRect(vec2 p, vec2 b, float r) { + vec2 q = abs(p) - (b - vec2(r)); + return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r; +} + +void main() { + if (ubuf.rippleOpacity <= 0.0 || ubuf.rippleRadius <= 0.0) { + fragColor = vec4(0.0); + return; + } + + vec2 px = qt_TexCoord0 * vec2(ubuf.widthPx, ubuf.heightPx) + vec2(ubuf.offsetX, ubuf.offsetY); + + float circleD = length(px - vec2(ubuf.rippleCenterX, ubuf.rippleCenterY)) - ubuf.rippleRadius; + float aaCircle = max(fwidth(circleD), 0.001); + float circleMask = 1.0 - smoothstep(-aaCircle, aaCircle, circleD); + if (circleMask <= 0.0) { + fragColor = vec4(0.0); + return; + } + + float rrMask = 1.0; + if (ubuf.cornerRadiusPx > 0.0) { + vec2 halfSize = vec2(ubuf.parentWidth, ubuf.parentHeight) * 0.5; + float r = clamp(ubuf.cornerRadiusPx, 0.0, min(halfSize.x, halfSize.y)); + float rrD = sdRoundRect(px - halfSize, halfSize, r); + float aaRR = max(fwidth(rrD), 0.001); + rrMask = 1.0 - smoothstep(-aaRR, aaRR, rrD); + } + + float mask = circleMask * rrMask; + if (mask <= 0.0) { + fragColor = vec4(0.0); + return; + } + + float a = ubuf.rippleCol.a * ubuf.rippleOpacity * mask * ubuf.qt_Opacity; + fragColor = vec4(ubuf.rippleCol.rgb * a, a); +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_disc.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_disc.frag new file mode 100644 index 0000000..254ae41 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_disc.frag @@ -0,0 +1,126 @@ +// ===== wp_disc.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; // Current wallpaper +layout(binding = 2) uniform sampler2D source2; // Next wallpaper + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; // Transition progress (0.0 to 1.0) + float centerX; // X coordinate of disc center (0.0 to 1.0) + float centerY; // Y coordinate of disc center (0.0 to 1.0) + float smoothness; // Edge smoothness (0.0 to 1.0, 0=sharp, 1=very smooth) + float aspectRatio; // Width / Height of the screen + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + + // Sample textures with fill mode + vec4 color1 = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 color2 = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + // Map smoothness from 0.0-1.0 to 0.001-0.5 range + // Using a non-linear mapping for better control + float mappedSmoothness = mix(0.001, 0.5, ubuf.smoothness * ubuf.smoothness); + + // Adjust UV coordinates to compensate for aspect ratio + // This makes distances circular instead of elliptical + vec2 adjustedUV = vec2(uv.x * ubuf.aspectRatio, uv.y); + vec2 adjustedCenter = vec2(ubuf.centerX * ubuf.aspectRatio, ubuf.centerY); + + // Calculate distance in aspect-corrected space + float dist = distance(adjustedUV, adjustedCenter); + + // Calculate the maximum possible distance (corner to corner) + // This ensures the disc can cover the entire screen + float maxDistX = max(ubuf.centerX * ubuf.aspectRatio, + (1.0 - ubuf.centerX) * ubuf.aspectRatio); + float maxDistY = max(ubuf.centerY, 1.0 - ubuf.centerY); + float maxDist = length(vec2(maxDistX, maxDistY)); + + // Scale progress to cover the maximum distance + // Add extra range for smoothness to ensure complete coverage + // Adjust smoothness for aspect ratio to maintain consistent visual appearance + float adjustedSmoothness = mappedSmoothness * max(1.0, ubuf.aspectRatio); + float radius = ubuf.progress * (maxDist + adjustedSmoothness); + + // Use smoothstep for a smooth edge transition + float factor = smoothstep(radius - adjustedSmoothness, radius + adjustedSmoothness, dist); + + // Mix the textures (factor = 0 inside disc, 1 outside) + fragColor = mix(color2, color1, factor); + + if (ubuf.progress <= 0.0) fragColor = color1; + + fragColor *= ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_fade.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_fade.frag new file mode 100644 index 0000000..31a404d --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_fade.frag @@ -0,0 +1,91 @@ +// ===== wp_fade.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; +layout(binding = 2) uniform sampler2D source2; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; + + // Fill mode parameters + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; // Width of source1 image + float imageHeight1; // Height of source1 image + float imageWidth2; // Width of source2 image + float imageHeight2; // Height of source2 image + float screenWidth; // Screen width + float screenHeight; // Screen height + vec4 fillColor; // Fill color for empty areas (default: black) +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + + // Sample textures with fill mode + vec4 color1 = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 color2 = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + // Mix the two textures based on progress value + fragColor = mix(color1, color2, ubuf.progress) * ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_iris_bloom.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_iris_bloom.frag new file mode 100644 index 0000000..548d5bd --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_iris_bloom.frag @@ -0,0 +1,119 @@ +// ===== wp_iris_bloom.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; +layout(binding = 2) uniform sampler2D source2; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; + float centerX; + float centerY; + float smoothness; + float aspectRatio; + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + vec4 color1 = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 color2 = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + float edgeSoft = mix(0.001, 0.45, ubuf.smoothness * ubuf.smoothness); + + vec2 center = vec2(ubuf.centerX, ubuf.centerY); + vec2 acUv = vec2(uv.x * ubuf.aspectRatio, uv.y); + vec2 acCenter = vec2(center.x * ubuf.aspectRatio, center.y); + vec2 q = acUv - acCenter; + + float maxX = max(center.x * ubuf.aspectRatio, (1.0 - center.x) * ubuf.aspectRatio); + float maxY = max(center.y, 1.0 - center.y); + float maxDist = length(vec2(maxX, maxY)); + + float p = ubuf.progress; + p = p * p * (3.0 - 2.0 * p); + + float radius = p * maxDist; + + // squash factor for the "eye" slit + float squash = mix(0.2, 1.0, p); + q.y /= squash; + + float dist = length(q); + float t = smoothstep(radius - edgeSoft, radius + edgeSoft, dist); + + vec4 col = mix(color2, color1, t); + + if (ubuf.progress <= 0.0) col = color1; + if (ubuf.progress >= 1.0) col = color2; + + fragColor = col * ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_pixelate.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_pixelate.frag new file mode 100644 index 0000000..2b6fb53 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_pixelate.frag @@ -0,0 +1,125 @@ +// ===== wp_pixelate.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; // Current wallpaper (underlay) +layout(binding = 2) uniform sampler2D source2; // Next wallpaper (pixelated overlay → sharp) + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; // 0..1 + float centerX; // (unused, API compat) + float centerY; // (unused) + float smoothness; // controls starting block size (0..1) + float aspectRatio; // (unused) + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +vec2 quantizeUV(vec2 uv, float cellPx) { + vec2 screenSize = vec2(max(1.0, ubuf.screenWidth), max(1.0, ubuf.screenHeight)); + float cell = max(1.0, ceil(cellPx)); // integer pixel cells + vec2 grid = floor(uv * screenSize / cell) * cell + 0.5 * cell; + return grid / screenSize; +} + +void main() { + vec2 uv = qt_TexCoord0; + + vec4 oldCol = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + + float p = clamp(ubuf.progress, 0.0, 1.0); + float pe = p * p * (3.0 - 2.0 * p); // smootherstep for opacity + + // Screen-relative starting cell size: + // smoothness=0 → ~10% of min(screen), smoothness=1 → ~80% of min(screen) + float s = clamp(ubuf.smoothness, 0.0, 1.0); + float minSide = min(max(1.0, ubuf.screenWidth), max(1.0, ubuf.screenHeight)); + float startPx = mix(minSide * 0.10, minSide * 0.80, s); // big and obvious even on small screens + + // Cell size shrinks continuously from startPx → 1 as p grows + float cellPx = mix(startPx, 1.0, p); + + // Sample next as pixelated overlay + vec2 uvq = quantizeUV(uv, cellPx); + vec4 newPix = sampleWithFillMode(source2, uvq, ubuf.imageWidth2, ubuf.imageHeight2); + + // As we approach the end, sharpen the next from pixelated → full-res + float sharpen = smoothstep(0.75, 1.0, p); // only near the end + vec4 newFull = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + vec4 newCol = mix(newPix, newFull, sharpen); + + vec4 outColor = mix(oldCol, newCol, pe); + + // Snaps + if (p <= 0.0) outColor = oldCol; + if (p >= 1.0) outColor = newFull; + + fragColor = outColor * ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_portal.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_portal.frag new file mode 100644 index 0000000..21e939c --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_portal.frag @@ -0,0 +1,124 @@ +// ===== wp_portal.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; // Current wallpaper (shrinks away) +layout(binding = 2) uniform sampler2D source2; // Next wallpaper (underneath) + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; // 0..1 + float centerX; // 0..1 + float centerY; // 0..1 + float smoothness; // 0..1 (edge softness) + float aspectRatio; // width / height + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + + vec4 oldCol = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 newCol = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + // Edge softness + float edgeSoft = mix(0.001, 0.45, ubuf.smoothness * ubuf.smoothness); + + // Aspect-corrected distance from center (keep circle round) + vec2 center = vec2(ubuf.centerX, ubuf.centerY); + vec2 acUv = vec2(uv.x * ubuf.aspectRatio, uv.y); + vec2 acCenter = vec2(center.x * ubuf.aspectRatio, center.y); + float dist = length(acUv - acCenter); + + // Max radius from center to cover screen + float maxDistX = max(center.x * ubuf.aspectRatio, (1.0 - center.x) * ubuf.aspectRatio); + float maxDistY = max(center.y, 1.0 - center.y); + float maxDist = length(vec2(maxDistX, maxDistY)); + + // Smooth easing for a friendly feel + float p = ubuf.progress; + p = p * p * (3.0 - 2.0 * p); + + // Portal radius shrinks from full to zero (bias by edgeSoft so it vanishes cleanly) + float radius = (1.0 - p) * (maxDist + edgeSoft) - edgeSoft; + + // Inside circle = old wallpaper; outside = new wallpaper + float t = smoothstep(radius - edgeSoft, radius + edgeSoft, dist); + // When radius is large: t ~ 0 inside (old), ~1 outside (new) + // As radius shrinks, old area collapses to center. + + vec4 col = mix(oldCol, newCol, t); + + // Snaps + if (ubuf.progress <= 0.0) col = oldCol; // full old at start + if (ubuf.progress >= 1.0) col = newCol; // full new at end + + fragColor = col * ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_stripes.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_stripes.frag new file mode 100644 index 0000000..fcc216b --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_stripes.frag @@ -0,0 +1,205 @@ +// ===== wp_stripes.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; // Current wallpaper +layout(binding = 2) uniform sampler2D source2; // Next wallpaper + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; // Transition progress (0.0 to 1.0) + float stripeCount; // Number of stripes (default 12.0) + float angle; // Angle of stripes in degrees (default 30.0) + float smoothness; // Edge smoothness (0.0 to 1.0, 0=sharp, 1=very smooth) + float aspectRatio; // Width / Height of the screen + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + + // Sample textures with fill mode + vec4 color1 = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 color2 = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + // Map smoothness from 0.0-1.0 to 0.001-0.3 range + // Using a non-linear mapping for better control at low values + float mappedSmoothness = mix(0.001, 0.3, ubuf.smoothness * ubuf.smoothness); + + // Use values directly without forcing defaults + float stripes = (ubuf.stripeCount > 0.0) ? ubuf.stripeCount : 12.0; + float angleRad = radians(ubuf.angle); + float edgeSmooth = mappedSmoothness; + + // Create a coordinate system for stripes based on angle + // At 0°: vertical stripes (divide by x) + // At 45°: diagonal stripes + // At 90°: horizontal stripes (divide by y) + + // Transform coordinates based on angle + float cosA = cos(angleRad); + float sinA = sin(angleRad); + + // Project the UV position onto the stripe direction + // This gives us the position along the stripe direction + float stripeCoord = uv.x * cosA + uv.y * sinA; + + // Perpendicular coordinate (for edge movement) + float perpCoord = -uv.x * sinA + uv.y * cosA; + + // Calculate the range of perpCoord based on angle + // This determines how far edges need to travel to fully cover the screen + float minPerp = min(min(0.0 * -sinA + 0.0 * cosA, 1.0 * -sinA + 0.0 * cosA), + min(0.0 * -sinA + 1.0 * cosA, 1.0 * -sinA + 1.0 * cosA)); + float maxPerp = max(max(0.0 * -sinA + 0.0 * cosA, 1.0 * -sinA + 0.0 * cosA), + max(0.0 * -sinA + 1.0 * cosA, 1.0 * -sinA + 1.0 * cosA)); + + // Determine which stripe we're in + float stripePos = stripeCoord * stripes; + int stripeIndex = int(floor(stripePos)); + + // Determine if this is an odd or even stripe + bool isOddStripe = mod(float(stripeIndex), 2.0) != 0.0; + + // Calculate the progress for this specific stripe with wave delay + // Use absolute stripe position for consistent delay across all stripes + float normalizedStripePos = clamp(stripePos / stripes, 0.0, 1.0); + + // Increased delay and better distribution + float maxDelay = 0.1; + float stripeDelay = normalizedStripePos * maxDelay; + + // Better progress mapping that uses the full 0.0-1.0 range + // Map progress so that: + // - First stripe starts at progress = 0.0 + // - Last stripe finishes at progress = 1.0 + float stripeProgress; + if (ubuf.progress <= stripeDelay) { + stripeProgress = 0.0; + } else if (ubuf.progress >= (stripeDelay + (1.0 - maxDelay))) { + stripeProgress = 1.0; + } else { + // Scale the progress within the active window for this stripe + float activeStart = stripeDelay; + float activeEnd = stripeDelay + (1.0 - maxDelay); + stripeProgress = (ubuf.progress - activeStart) / (activeEnd - activeStart); + } + + // Use gentler easing curve + stripeProgress = stripeProgress * stripeProgress * (3.0 - 2.0 * stripeProgress); // Smootherstep instead of smoothstep + + // Use the perpendicular coordinate for edge comparison + float yPos = perpCoord; + + // Calculate edge position for this stripe + // Use the actual perpendicular coordinate range for this angle + float perpRange = maxPerp - minPerp; + float margin = edgeSmooth * 2.0; // Simplified margin calculation + float edgePosition; + if (isOddStripe) { + // Odd stripes: edge moves from max to min + edgePosition = maxPerp + margin - stripeProgress * (perpRange + margin * 2.0); + } else { + // Even stripes: edge moves from min to max + edgePosition = minPerp - margin + stripeProgress * (perpRange + margin * 2.0); + } + + // Determine which wallpaper to show based on rotated position + float mask; + if (isOddStripe) { + // Odd stripes reveal new wallpaper from bottom + mask = smoothstep(edgePosition - edgeSmooth, edgePosition + edgeSmooth, yPos); + } else { + // Even stripes reveal new wallpaper from top + mask = 1.0 - smoothstep(edgePosition - edgeSmooth, edgePosition + edgeSmooth, yPos); + } + + // Mix the wallpapers + fragColor = mix(color1, color2, mask); + + // Force exact values at start and end to prevent any bleed-through + if (ubuf.progress <= 0.0) { + fragColor = color1; // Only show old wallpaper at start + } else if (ubuf.progress >= 1.0) { + fragColor = color2; // Only show new wallpaper at end + } else { + // Add manga-style edge shadow only during transition + float edgeDist = abs(yPos - edgePosition); + float shadowStrength = 1.0 - smoothstep(0.0, edgeSmooth * 2.5, edgeDist); + shadowStrength *= 0.2 * (1.0 - abs(stripeProgress - 0.5) * 2.0); + fragColor.rgb *= (1.0 - shadowStrength); + + // Add slight vignette during transition for dramatic effect + float vignette = 1.0 - ubuf.progress * 0.1 * (1.0 - abs(stripeProgress - 0.5) * 2.0); + fragColor.rgb *= vignette; + } + + fragColor *= ubuf.qt_Opacity; +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_wipe.frag b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_wipe.frag new file mode 100644 index 0000000..5fc6d32 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Shaders/frag/wp_wipe.frag @@ -0,0 +1,129 @@ +// ===== wp_wipe.frag ===== +#version 450 + +layout(location = 0) in vec2 qt_TexCoord0; +layout(location = 0) out vec4 fragColor; + +layout(binding = 1) uniform sampler2D source1; // Current wallpaper +layout(binding = 2) uniform sampler2D source2; // Next wallpaper + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float progress; // Transition progress (0.0 to 1.0) + float direction; // 0=left, 1=right, 2=up, 3=down + float smoothness; // Edge smoothness (0.0 to 1.0, 0=sharp, 1=very smooth) + + float fillMode; // 0=stretch, 1=fit, 2=crop, 3=tile, 4=tileV, 5=tileH, 6=pad + float imageWidth1; + float imageHeight1; + float imageWidth2; + float imageHeight2; + float screenWidth; + float screenHeight; + vec4 fillColor; +} ubuf; + +vec2 calculateUV(vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = uv; + + if (ubuf.fillMode < 0.5) { + transformedUV = uv; + } + else if (ubuf.fillMode < 1.5) { + float scale = min(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - scaledImageSize) * 0.5; + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imagePixel = (screenPixel - offset) / scale; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + else if (ubuf.fillMode < 2.5) { + float scale = max(ubuf.screenWidth / imgWidth, ubuf.screenHeight / imgHeight); + vec2 scaledImageSize = vec2(imgWidth, imgHeight) * scale; + vec2 offset = (scaledImageSize - vec2(ubuf.screenWidth, ubuf.screenHeight)) / scaledImageSize; + transformedUV = uv * (vec2(1.0) - offset) + offset * 0.5; + } + else if (ubuf.fillMode < 3.5) { + transformedUV = fract(uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight)); + } + else if (ubuf.fillMode < 4.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(uv.x, fract(tileUV.y)); + } + else if (ubuf.fillMode < 5.5) { + vec2 tileUV = uv * vec2(ubuf.screenWidth, ubuf.screenHeight) / vec2(imgWidth, imgHeight); + transformedUV = vec2(fract(tileUV.x), uv.y); + } + else { + vec2 screenPixel = uv * vec2(ubuf.screenWidth, ubuf.screenHeight); + vec2 imageOffset = (vec2(ubuf.screenWidth, ubuf.screenHeight) - vec2(imgWidth, imgHeight)) * 0.5; + vec2 imagePixel = screenPixel - imageOffset; + transformedUV = imagePixel / vec2(imgWidth, imgHeight); + } + + return transformedUV; +} + +vec4 sampleWithFillMode(sampler2D tex, vec2 uv, float imgWidth, float imgHeight) { + vec2 transformedUV = calculateUV(uv, imgWidth, imgHeight); + + if (ubuf.fillMode >= 2.5 && ubuf.fillMode <= 5.5) { + return texture(tex, transformedUV); + } + + if (transformedUV.x < 0.0 || transformedUV.x > 1.0 || + transformedUV.y < 0.0 || transformedUV.y > 1.0) { + return ubuf.fillColor; + } + + return texture(tex, transformedUV); +} + +void main() { + vec2 uv = qt_TexCoord0; + + // Sample textures with fill mode + vec4 color1 = sampleWithFillMode(source1, uv, ubuf.imageWidth1, ubuf.imageHeight1); + vec4 color2 = sampleWithFillMode(source2, uv, ubuf.imageWidth2, ubuf.imageHeight2); + + // Map smoothness from 0.0-1.0 to 0.001-0.5 range + // Using a non-linear mapping for better control + float mappedSmoothness = mix(0.001, 0.5, ubuf.smoothness * ubuf.smoothness); + + float edge = 0.0; + float factor = 0.0; + + // Extend the progress range to account for smoothness + // This ensures the transition completes fully at the edges + float extendedProgress = ubuf.progress * (1.0 + 2.0 * mappedSmoothness) - mappedSmoothness; + + // Calculate edge position based on direction + // As progress goes from 0 to 1, we reveal source2 (new wallpaper) + if (ubuf.direction < 0.5) { + // Wipe from right to left (new image enters from right) + edge = 1.0 - extendedProgress; + factor = smoothstep(edge - mappedSmoothness, edge + mappedSmoothness, uv.x); + fragColor = mix(color1, color2, factor); + } + else if (ubuf.direction < 1.5) { + // Wipe from left to right (new image enters from left) + edge = extendedProgress; + factor = smoothstep(edge - mappedSmoothness, edge + mappedSmoothness, uv.x); + fragColor = mix(color2, color1, factor); + } + else if (ubuf.direction < 2.5) { + // Wipe from bottom to top (new image enters from bottom) + edge = 1.0 - extendedProgress; + factor = smoothstep(edge - mappedSmoothness, edge + mappedSmoothness, uv.y); + fragColor = mix(color1, color2, factor); + } + else { + // Wipe from top to bottom (new image enters from top) + edge = extendedProgress; + factor = smoothstep(edge - mappedSmoothness, edge + mappedSmoothness, uv.y); + fragColor = mix(color2, color1, factor); + } + + fragColor *= ubuf.qt_Opacity; +} -- cgit v1.3