better quickshell
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 qt_TexCoord0;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D source;
|
||||
|
||||
layout(std140, binding = 0) uniform buf {
|
||||
mat4 qt_Matrix;
|
||||
float qt_Opacity;
|
||||
// Custom properties with non-conflicting names
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
float sourceWidth;
|
||||
float sourceHeight;
|
||||
float cornerRadius;
|
||||
float imageOpacity;
|
||||
int fillMode;
|
||||
} ubuf;
|
||||
|
||||
// Function to calculate the signed distance from a point to a rounded box
|
||||
float roundedBoxSDF(vec2 centerPos, vec2 boxSize, float radius) {
|
||||
vec2 d = abs(centerPos) - boxSize + radius;
|
||||
return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0) - radius;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Get size from uniforms
|
||||
vec2 itemSize = vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 sourceSize = vec2(ubuf.sourceWidth, ubuf.sourceHeight);
|
||||
float cornerRadius = ubuf.cornerRadius;
|
||||
float itemOpacity = ubuf.imageOpacity;
|
||||
int fillMode = ubuf.fillMode;
|
||||
|
||||
// Work in pixel space for accurate rounded rectangle calculation
|
||||
vec2 pixelPos = qt_TexCoord0 * itemSize;
|
||||
|
||||
// Calculate UV coordinates based on fill mode
|
||||
vec2 imageUV = qt_TexCoord0;
|
||||
|
||||
// fillMode constants from Qt:
|
||||
// Image.Stretch = 0
|
||||
// Image.PreserveAspectFit = 1
|
||||
// Image.PreserveAspectCrop = 2
|
||||
// Image.Tile = 3
|
||||
// Image.TileVertically = 4
|
||||
// Image.TileHorizontally = 5
|
||||
// Image.Pad = 6
|
||||
|
||||
// Rounded corners always apply to full item bounds
|
||||
vec2 roundedSize = itemSize;
|
||||
vec2 roundedCenter = itemSize * 0.5;
|
||||
|
||||
// Track if pixel is in letterbox area (for PreserveAspectFit)
|
||||
bool inLetterbox = false;
|
||||
|
||||
if (fillMode == 1) { // PreserveAspectFit
|
||||
float itemAspect = itemSize.x / itemSize.y;
|
||||
float sourceAspect = sourceSize.x / sourceSize.y;
|
||||
|
||||
if (sourceAspect > itemAspect) {
|
||||
// Image is wider than item, letterbox top/bottom
|
||||
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
|
||||
} else {
|
||||
// Image is taller than item, letterbox left/right
|
||||
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
|
||||
}
|
||||
|
||||
// Check if in letterbox area
|
||||
inLetterbox = (imageUV.x < 0.0 || imageUV.x > 1.0 || imageUV.y < 0.0 || imageUV.y > 1.0);
|
||||
} else if (fillMode == 2) { // PreserveAspectCrop
|
||||
float itemAspect = itemSize.x / itemSize.y;
|
||||
float sourceAspect = sourceSize.x / sourceSize.y;
|
||||
|
||||
if (sourceAspect > itemAspect) {
|
||||
// Image is wider than item, crop left/right.
|
||||
imageUV.x = (qt_TexCoord0.x - 0.5) * (itemAspect / sourceAspect) + 0.5;
|
||||
} else {
|
||||
// Image is taller than item, crop top/bottom.
|
||||
imageUV.y = (qt_TexCoord0.y - 0.5) * (sourceAspect / itemAspect) + 0.5;
|
||||
}
|
||||
}
|
||||
// For Stretch (0) or other modes, use qt_TexCoord0 as-is
|
||||
|
||||
// Calculate distance to rounded rectangle edge using the correct bounds
|
||||
vec2 centerOffset = pixelPos - roundedCenter;
|
||||
float distance = roundedBoxSDF(centerOffset, roundedSize * 0.5, cornerRadius);
|
||||
|
||||
// Create smooth alpha mask for edge with anti-aliasing
|
||||
float alpha = 1.0 - smoothstep(-0.5, 0.5, distance);
|
||||
|
||||
// Sample the texture (or use transparent for letterbox)
|
||||
vec4 color = inLetterbox ? vec4(0.0) : texture(source, imageUV);
|
||||
|
||||
// Apply the rounded mask and opacity
|
||||
float finalAlpha = color.a * alpha * itemOpacity * ubuf.qt_Opacity;
|
||||
fragColor = vec4(color.rgb * finalAlpha, finalAlpha);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
#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 time;
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
vec4 bgColor;
|
||||
float cornerRadius;
|
||||
float alternative;
|
||||
} ubuf;
|
||||
|
||||
// Signed distance function for rounded rectangle
|
||||
float roundedBoxSDF(vec2 center, vec2 size, float radius) {
|
||||
vec2 q = abs(center) - size + radius;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
|
||||
}
|
||||
|
||||
float hash(vec2 p) {
|
||||
p = fract(p * vec2(234.34, 435.345));
|
||||
p += dot(p, p + 34.23);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
// Perlin-like noise
|
||||
float noise(vec2 p) {
|
||||
vec2 i = floor(p);
|
||||
vec2 f = fract(p);
|
||||
f = f * f * (3.0 - 2.0 * f); // Smooth interpolation
|
||||
float a = hash(i);
|
||||
float b = hash(i + vec2(1.0, 0.0));
|
||||
float c = hash(i + vec2(0.0, 1.0));
|
||||
float d = hash(i + vec2(1.0, 1.0));
|
||||
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
||||
}
|
||||
|
||||
// Turbulent noise for natural fog
|
||||
float turbulence(vec2 p, float iTime) {
|
||||
float t = 0.0;
|
||||
float scale = 1.0;
|
||||
for(int i = 0; i < 5; i++) {
|
||||
t += abs(noise(p * scale + iTime * 0.1 * scale)) / scale;
|
||||
scale *= 2.0;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = qt_TexCoord0;
|
||||
|
||||
vec4 col = vec4(ubuf.bgColor.rgb, 1.0);
|
||||
|
||||
// Different parameters for fog vs clouds
|
||||
float timeSpeed, layerScale1, layerScale2, layerScale3;
|
||||
float flowSpeed1, flowSpeed2;
|
||||
float densityMin, densityMax;
|
||||
float baseOpacity;
|
||||
float pulseAmount;
|
||||
|
||||
if (ubuf.alternative > 0.5) {
|
||||
// Fog: slower, larger scale, more uniform
|
||||
timeSpeed = 0.03;
|
||||
layerScale1 = 1.0;
|
||||
layerScale2 = 2.5;
|
||||
layerScale3 = 2.0;
|
||||
flowSpeed1 = 0.00;
|
||||
flowSpeed2 = 0.02;
|
||||
densityMin = 0.1;
|
||||
densityMax = 0.9;
|
||||
baseOpacity = 0.75;
|
||||
pulseAmount = 0.05;
|
||||
} else {
|
||||
// Clouds: faster, smaller scale, puffier
|
||||
timeSpeed = 0.08;
|
||||
layerScale1 = 2.0;
|
||||
layerScale2 = 4.0;
|
||||
layerScale3 = 6.0;
|
||||
flowSpeed1 = 0.03;
|
||||
flowSpeed2 = 0.04;
|
||||
densityMin = 0.35;
|
||||
densityMax = 0.75;
|
||||
baseOpacity = 0.4;
|
||||
pulseAmount = 0.15;
|
||||
}
|
||||
|
||||
float iTime = ubuf.time * timeSpeed;
|
||||
|
||||
// Create flowing patterns with multiple layers
|
||||
vec2 flow1 = vec2(iTime * flowSpeed1, iTime * flowSpeed1 * 0.7);
|
||||
vec2 flow2 = vec2(-iTime * flowSpeed2, iTime * flowSpeed2 * 0.8);
|
||||
|
||||
float fog1 = noise(uv * layerScale1 + flow1);
|
||||
float fog2 = noise(uv * layerScale2 + flow2);
|
||||
float fog3 = turbulence(uv * layerScale3, iTime);
|
||||
|
||||
float fogPattern = fog1 * 0.5 + fog2 * 0.3 + fog3 * 0.2;
|
||||
float fogDensity = smoothstep(densityMin, densityMax, fogPattern);
|
||||
|
||||
// Gentle pulsing
|
||||
float pulse = sin(iTime * 0.4) * pulseAmount + (1.0 - pulseAmount);
|
||||
fogDensity *= pulse;
|
||||
|
||||
vec3 hazeColor = vec3(0.88, 0.90, 0.93);
|
||||
float hazeOpacity = fogDensity * baseOpacity;
|
||||
vec3 fogContribution = hazeColor * hazeOpacity;
|
||||
float fogAlpha = hazeOpacity;
|
||||
|
||||
vec3 resultRGB = fogContribution + col.rgb * (1.0 - fogAlpha);
|
||||
float resultAlpha = fogAlpha + col.a * (1.0 - fogAlpha);
|
||||
|
||||
// Calculate corner mask
|
||||
vec2 pixelPos = qt_TexCoord0 * vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 center = pixelPos - vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
vec2 halfSize = vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
float dist = roundedBoxSDF(center, halfSize, ubuf.cornerRadius);
|
||||
float cornerMask = 1.0 - smoothstep(-1.0, 0.0, dist);
|
||||
|
||||
// Apply global opacity and corner mask
|
||||
float finalAlpha = resultAlpha * ubuf.qt_Opacity * cornerMask;
|
||||
fragColor = vec4(resultRGB * (finalAlpha / max(resultAlpha, 0.001)), finalAlpha);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#version 450
|
||||
|
||||
layout(location = 0) in vec2 qt_TexCoord0;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D source;
|
||||
|
||||
layout(std140, binding = 0) uniform buf {
|
||||
mat4 qt_Matrix;
|
||||
float qt_Opacity;
|
||||
float time;
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
vec4 bgColor;
|
||||
float cornerRadius;
|
||||
} ubuf;
|
||||
|
||||
// Signed distance function for rounded rectangle
|
||||
float roundedBoxSDF(vec2 center, vec2 size, float radius) {
|
||||
vec2 q = abs(center) - size + radius;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
|
||||
}
|
||||
|
||||
vec3 hash3(vec2 p) {
|
||||
vec3 q = vec3(dot(p, vec2(127.1, 311.7)),
|
||||
dot(p, vec2(269.5, 183.3)),
|
||||
dot(p, vec2(419.2, 371.9)));
|
||||
return fract(sin(q) * 43758.5453);
|
||||
}
|
||||
|
||||
float noise(vec2 x, float iTime) {
|
||||
vec2 p = floor(x);
|
||||
vec2 f = fract(x);
|
||||
|
||||
float va = 0.0;
|
||||
for (int j = -2; j <= 2; j++) {
|
||||
for (int i = -2; i <= 2; i++) {
|
||||
vec2 g = vec2(float(i), float(j));
|
||||
vec3 o = hash3(p + g);
|
||||
vec2 r = g - f + o.xy;
|
||||
float d = sqrt(dot(r, r));
|
||||
float ripple = max(mix(smoothstep(0.99, 0.999, max(cos(d - iTime * 2.0 + (o.x + o.y) * 5.0), 0.0)), 0.0, d), 0.0);
|
||||
va += ripple;
|
||||
}
|
||||
}
|
||||
|
||||
return va;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = qt_TexCoord0;
|
||||
float iTime = ubuf.time * 0.07;
|
||||
|
||||
// Aspect ratio correction for circular ripples
|
||||
float aspect = ubuf.itemWidth / ubuf.itemHeight;
|
||||
vec2 uvAspect = vec2(uv.x * aspect, uv.y);
|
||||
|
||||
float f = noise(6.0 * uvAspect, iTime) * smoothstep(0.0, 0.2, sin(uv.x * 3.141592) * sin(uv.y * 3.141592));
|
||||
|
||||
// Calculate normal from noise for distortion
|
||||
float normalScale = 0.5;
|
||||
vec2 e = normalScale / vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 eAspect = vec2(e.x * aspect, e.y);
|
||||
float cx = noise(6.0 * (uvAspect + eAspect), iTime) * smoothstep(0.0, 0.2, sin((uv.x + e.x) * 3.141592) * sin(uv.y * 3.141592));
|
||||
float cy = noise(6.0 * (uvAspect + eAspect.yx), iTime) * smoothstep(0.0, 0.2, sin(uv.x * 3.141592) * sin((uv.y + e.y) * 3.141592));
|
||||
vec2 n = vec2(cx - f, cy - f);
|
||||
|
||||
// Scale distortion back to texture space (undo aspect correction for X)
|
||||
vec2 distortion = vec2(n.x / aspect, n.y);
|
||||
|
||||
// Sample source with distortion
|
||||
vec4 col = texture(source, uv + distortion);
|
||||
|
||||
// Apply rounded corner mask
|
||||
vec2 pixelPos = qt_TexCoord0 * vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 center = pixelPos - vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
vec2 halfSize = vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
float dist = roundedBoxSDF(center, halfSize, ubuf.cornerRadius);
|
||||
float cornerMask = 1.0 - smoothstep(-1.0, 0.0, dist);
|
||||
|
||||
// Output with premultiplied alpha
|
||||
float finalAlpha = col.a * ubuf.qt_Opacity * cornerMask;
|
||||
fragColor = vec4(col.rgb * finalAlpha, finalAlpha);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#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 time;
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
vec4 bgColor;
|
||||
float cornerRadius;
|
||||
} ubuf;
|
||||
|
||||
// Signed distance function for rounded rectangle
|
||||
float roundedBoxSDF(vec2 center, vec2 size, float radius) {
|
||||
vec2 q = abs(center) - size + radius;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Aspect ratio correction
|
||||
float aspect = ubuf.itemWidth / ubuf.itemHeight;
|
||||
vec2 uv = qt_TexCoord0;
|
||||
uv.x *= aspect;
|
||||
uv.y = 1.0 - uv.y;
|
||||
|
||||
float iTime = ubuf.time * 0.15;
|
||||
|
||||
float snow = 0.0;
|
||||
|
||||
for (int k = 0; k < 6; k++) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
float cellSize = 2.0 + (float(i) * 3.0);
|
||||
float downSpeed = 0.3 + (sin(iTime * 0.4 + float(k + i * 20)) + 1.0) * 0.00008;
|
||||
|
||||
vec2 uvAnim = uv + vec2(
|
||||
0.01 * sin((iTime + float(k * 6185)) * 0.6 + float(i)) * (5.0 / float(i + 1)),
|
||||
downSpeed * (iTime + float(k * 1352)) * (1.0 / float(i + 1))
|
||||
);
|
||||
|
||||
vec2 uvStep = (ceil((uvAnim) * cellSize - vec2(0.5, 0.5)) / cellSize);
|
||||
float x = fract(sin(dot(uvStep.xy, vec2(12.9898 + float(k) * 12.0, 78.233 + float(k) * 315.156))) * 43758.5453 + float(k) * 12.0) - 0.5;
|
||||
float y = fract(sin(dot(uvStep.xy, vec2(62.2364 + float(k) * 23.0, 94.674 + float(k) * 95.0))) * 62159.8432 + float(k) * 12.0) - 0.5;
|
||||
|
||||
float randomMagnitude1 = sin(iTime * 2.5) * 0.7 / cellSize;
|
||||
float randomMagnitude2 = cos(iTime * 1.65) * 0.7 / cellSize;
|
||||
|
||||
float d = 5.0 * distance((uvStep.xy + vec2(x * sin(y), y) * randomMagnitude1 + vec2(y, x) * randomMagnitude2), uvAnim.xy);
|
||||
|
||||
float omiVal = fract(sin(dot(uvStep.xy, vec2(32.4691, 94.615))) * 31572.1684);
|
||||
if (omiVal < 0.03) {
|
||||
float newd = (x + 1.0) * 0.4 * clamp(1.9 - d * (15.0 + (x * 6.3)) * (cellSize / 1.4), 0.0, 1.0);
|
||||
snow += newd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blend white snow over background color
|
||||
float snowAlpha = clamp(snow * 2.0, 0.0, 1.0);
|
||||
vec3 snowColor = vec3(1.0);
|
||||
vec3 blended = mix(ubuf.bgColor.rgb, snowColor, snowAlpha);
|
||||
|
||||
// Apply rounded corner mask
|
||||
vec2 pixelPos = qt_TexCoord0 * vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 center = pixelPos - vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
vec2 halfSize = vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
float dist = roundedBoxSDF(center, halfSize, ubuf.cornerRadius);
|
||||
float cornerMask = 1.0 - smoothstep(-1.0, 0.0, dist);
|
||||
|
||||
// Output with premultiplied alpha
|
||||
float finalAlpha = ubuf.qt_Opacity * cornerMask;
|
||||
fragColor = vec4(blended * finalAlpha, finalAlpha);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
#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 time;
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
vec4 bgColor;
|
||||
float cornerRadius;
|
||||
} ubuf;
|
||||
|
||||
// Signed distance function for rounded rectangle
|
||||
float roundedBoxSDF(vec2 center, vec2 size, float radius) {
|
||||
vec2 q = abs(center) - size + radius;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
|
||||
}
|
||||
|
||||
float hash(vec2 p) {
|
||||
p = fract(p * vec2(234.34, 435.345));
|
||||
p += dot(p, p + 34.23);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
vec2 hash2(vec2 p) {
|
||||
p = fract(p * vec2(234.34, 435.345));
|
||||
p += dot(p, p + 34.23);
|
||||
return fract(vec2(p.x * p.y, p.y * p.x));
|
||||
}
|
||||
|
||||
float stars(vec2 uv, float density, float iTime) {
|
||||
vec2 gridUV = uv * density;
|
||||
vec2 gridID = floor(gridUV);
|
||||
vec2 gridPos = fract(gridUV);
|
||||
|
||||
float starField = 0.0;
|
||||
|
||||
// Check neighboring cells for stars
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
vec2 offset = vec2(float(x), float(y));
|
||||
vec2 cellID = gridID + offset;
|
||||
|
||||
// Random position within cell
|
||||
vec2 starPos = hash2(cellID);
|
||||
|
||||
// Only create a star for some cells (sparse distribution)
|
||||
float starChance = hash(cellID + vec2(12.345, 67.890));
|
||||
if (starChance > 0.85) {
|
||||
// Star position in grid space
|
||||
vec2 toStar = (offset + starPos - gridPos);
|
||||
float dist = length(toStar) * density; // Scale distance to pixel space
|
||||
|
||||
float starSize = 1.5;
|
||||
|
||||
// Star brightness variation
|
||||
float brightness = hash(cellID + vec2(23.456, 78.901)) * 0.6 + 0.4;
|
||||
|
||||
// Twinkling effect
|
||||
float twinkleSpeed = hash(cellID + vec2(34.567, 89.012)) * 3.0 + 2.0;
|
||||
float twinklePhase = iTime * twinkleSpeed + hash(cellID) * 6.28;
|
||||
float twinkle = pow(sin(twinklePhase) * 0.5 + 0.5, 3.0); // Sharp on/off
|
||||
|
||||
// Sharp star core
|
||||
float star = 0.0;
|
||||
if (dist < starSize) {
|
||||
star = 1.0 * brightness * (0.3 + twinkle * 0.7);
|
||||
|
||||
// Add tiny cross-shaped glow for brighter stars
|
||||
if (brightness > 0.7) {
|
||||
float crossGlow = max(
|
||||
exp(-abs(toStar.x) * density * 5.0),
|
||||
exp(-abs(toStar.y) * density * 5.0)
|
||||
) * 0.3 * twinkle;
|
||||
star += crossGlow;
|
||||
}
|
||||
}
|
||||
|
||||
starField += star;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return starField;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = qt_TexCoord0;
|
||||
float iTime = ubuf.time * 0.01;
|
||||
|
||||
// Base background color
|
||||
vec4 col = vec4(ubuf.bgColor.rgb, 1.0);
|
||||
|
||||
// Aspect ratio for consistent stars
|
||||
float aspect = ubuf.itemWidth / ubuf.itemHeight;
|
||||
vec2 uvAspect = vec2(uv.x * aspect, uv.y);
|
||||
|
||||
// Generate multiple layers of stars at different densities
|
||||
float stars1 = stars(uvAspect, 40.0, iTime); // Tiny distant stars
|
||||
float stars2 = stars(uvAspect + vec2(0.5, 0.3), 25.0, iTime * 1.3); // Small stars
|
||||
float stars3 = stars(uvAspect + vec2(0.25, 0.7), 15.0, iTime * 0.9); // Bigger stars
|
||||
|
||||
// Star colors with slight variation
|
||||
vec3 starColor1 = vec3(0.85, 0.9, 1.0); // Faint blue-white
|
||||
vec3 starColor2 = vec3(0.95, 0.97, 1.0); // White
|
||||
vec3 starColor3 = vec3(1.0, 0.98, 0.95); // Warm white
|
||||
|
||||
// Combine star layers
|
||||
vec3 starsRGB = starColor1 * stars1 * 0.6 +
|
||||
starColor2 * stars2 * 0.8 +
|
||||
starColor3 * stars3 * 1.0;
|
||||
|
||||
float starsAlpha = clamp(stars1 * 0.6 + stars2 * 0.8 + stars3, 0.0, 1.0);
|
||||
|
||||
// Apply rounded corner mask
|
||||
vec2 pixelPos = qt_TexCoord0 * vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 center = pixelPos - vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
vec2 halfSize = vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
float dist = roundedBoxSDF(center, halfSize, ubuf.cornerRadius);
|
||||
float cornerMask = 1.0 - smoothstep(-1.0, 0.0, dist);
|
||||
|
||||
// Add stars on top
|
||||
vec3 resultRGB = starsRGB * starsAlpha + col.rgb * (1.0 - starsAlpha);
|
||||
float resultAlpha = starsAlpha + col.a * (1.0 - starsAlpha);
|
||||
|
||||
// Apply global opacity and corner mask
|
||||
float finalAlpha = resultAlpha * ubuf.qt_Opacity * cornerMask;
|
||||
fragColor = vec4(resultRGB * (finalAlpha / max(resultAlpha, 0.001)), finalAlpha);
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
#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 time;
|
||||
float itemWidth;
|
||||
float itemHeight;
|
||||
vec4 bgColor;
|
||||
float cornerRadius;
|
||||
} ubuf;
|
||||
|
||||
// Signed distance function for rounded rectangle
|
||||
float roundedBoxSDF(vec2 center, vec2 size, float radius) {
|
||||
vec2 q = abs(center) - size + radius;
|
||||
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius;
|
||||
}
|
||||
|
||||
float hash(vec2 p) {
|
||||
p = fract(p * vec2(234.34, 435.345));
|
||||
p += dot(p, p + 34.23);
|
||||
return fract(p.x * p.y);
|
||||
}
|
||||
|
||||
float noise(vec2 p) {
|
||||
vec2 i = floor(p);
|
||||
vec2 f = fract(p);
|
||||
f = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
float a = hash(i);
|
||||
float b = hash(i + vec2(1.0, 0.0));
|
||||
float c = hash(i + vec2(0.0, 1.0));
|
||||
float d = hash(i + vec2(1.0, 1.0));
|
||||
|
||||
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
||||
}
|
||||
|
||||
// God rays originating from sun position
|
||||
float sunRays(vec2 uv, vec2 sunPos, float iTime) {
|
||||
vec2 toSun = uv - sunPos;
|
||||
float angle = atan(toSun.y, toSun.x);
|
||||
float dist = length(toSun);
|
||||
|
||||
float rayCount = 7;
|
||||
|
||||
// Radial pattern
|
||||
float rays = sin(angle * rayCount + sin(iTime * 0.25)) * 0.5 + 0.5;
|
||||
rays = pow(rays, 3.0);
|
||||
|
||||
// Fade with distance
|
||||
float falloff = 1.0 - smoothstep(0.0, 1.2, dist);
|
||||
|
||||
return rays * falloff * 0.15;
|
||||
}
|
||||
|
||||
// Atmospheric shimmer / heat haze
|
||||
float atmosphericShimmer(vec2 uv, float iTime) {
|
||||
// Multiple layers of noise for complexity
|
||||
float n1 = noise(uv * 5.0 + vec2(iTime * 0.1, iTime * 0.05));
|
||||
float n2 = noise(uv * 8.0 - vec2(iTime * 0.08, iTime * 0.12));
|
||||
float n3 = noise(uv * 12.0 + vec2(iTime * 0.15, -iTime * 0.1));
|
||||
|
||||
return (n1 * 0.5 + n2 * 0.3 + n3 * 0.2) * 0.15;
|
||||
}
|
||||
|
||||
float sunCore(vec2 uv, vec2 sunPos, float iTime) {
|
||||
vec2 toSun = uv - sunPos;
|
||||
float dist = length(toSun);
|
||||
|
||||
// Main bright spot
|
||||
float mainFlare = exp(-dist * 15.0) * 2.0;
|
||||
|
||||
// Secondary reflection spots along the line
|
||||
float flares = 0.0;
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
vec2 flarePos = sunPos + toSun * float(i) * 0.3;
|
||||
float flareDist = length(uv - flarePos);
|
||||
float flareSize = 0.02 + float(i) * 0.01;
|
||||
flares += smoothstep(flareSize * 2.0, flareSize * 0.5, flareDist) * (0.3 / float(i));
|
||||
}
|
||||
|
||||
// Pulsing effect
|
||||
float pulse = sin(iTime) * 0.1 + 0.9;
|
||||
|
||||
return (mainFlare + flares) * pulse;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = qt_TexCoord0;
|
||||
float iTime = ubuf.time * 0.08;
|
||||
|
||||
// Sample the source
|
||||
vec4 col = vec4(ubuf.bgColor.rgb, 1.0);
|
||||
|
||||
vec2 sunPos = vec2(0.85, 0.2);
|
||||
|
||||
// Aspect ratio correction
|
||||
float aspect = ubuf.itemWidth / ubuf.itemHeight;
|
||||
vec2 uvAspect = vec2(uv.x * aspect, uv.y);
|
||||
vec2 sunPosAspect = vec2(sunPos.x * aspect, sunPos.y);
|
||||
|
||||
// Generate sunny effects
|
||||
float rays = sunRays(uvAspect, sunPosAspect, iTime);
|
||||
float shimmerEffect = atmosphericShimmer(uv, iTime);
|
||||
float flare = sunCore(uvAspect, sunPosAspect, iTime);
|
||||
|
||||
// Warm sunny colors
|
||||
vec3 sunColor = vec3(1.0, 0.95, 0.7); // Warm golden yellow
|
||||
vec3 skyColor = vec3(0.9, 0.95, 1.0); // Light blue tint
|
||||
vec3 shimmerColor = vec3(1.0, 0.98, 0.85); // Subtle warm shimmer
|
||||
|
||||
// Apply rounded corner mask
|
||||
vec2 pixelPos = qt_TexCoord0 * vec2(ubuf.itemWidth, ubuf.itemHeight);
|
||||
vec2 center = pixelPos - vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
vec2 halfSize = vec2(ubuf.itemWidth, ubuf.itemHeight) * 0.5;
|
||||
float dist = roundedBoxSDF(center, halfSize, ubuf.cornerRadius);
|
||||
float cornerMask = 1.0 - smoothstep(-1.0, 0.0, dist);
|
||||
|
||||
vec3 resultRGB = col.rgb;
|
||||
float resultAlpha = col.a;
|
||||
|
||||
// Add sun rays
|
||||
vec3 raysContribution = sunColor * rays;
|
||||
float raysAlpha = rays * 0.4;
|
||||
resultRGB = raysContribution + resultRGB * (1.0 - raysAlpha);
|
||||
resultAlpha = raysAlpha + resultAlpha * (1.0 - raysAlpha);
|
||||
|
||||
// Add atmospheric shimmer
|
||||
vec3 shimmerContribution = shimmerColor * shimmerEffect;
|
||||
float shimmerAlpha = shimmerEffect * 0.1;
|
||||
resultRGB = shimmerContribution + resultRGB * (1.0 - shimmerAlpha);
|
||||
resultAlpha = shimmerAlpha + resultAlpha * (1.0 - shimmerAlpha);
|
||||
|
||||
// Add bright sun core
|
||||
vec3 flareContribution = sunColor * flare;
|
||||
float flareAlpha = clamp(flare, 0.0, 1.0) * 0.6;
|
||||
resultRGB = flareContribution + resultRGB * (1.0 - flareAlpha);
|
||||
resultAlpha = flareAlpha + resultAlpha * (1.0 - flareAlpha);
|
||||
|
||||
// Overall warm sunny tint
|
||||
resultRGB = mix(resultRGB, resultRGB * vec3(1.08, 1.04, 0.98), 0.15);
|
||||
|
||||
// Apply global opacity and corner mask
|
||||
float finalAlpha = resultAlpha * ubuf.qt_Opacity * cornerMask;
|
||||
fragColor = vec4(resultRGB * (finalAlpha / max(resultAlpha, 0.001)), finalAlpha);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user