#version 150
uniform vec2 size;
uniform vec2 location;
uniform vec4 radius;
uniform float thickness;
uniform float softness;
uniform sampler2D InputSampler;
uniform vec2 InputResolution;
uniform float Quality;
in vec2 texCoord;
out vec4 fragColor;
// ----------------- SDF -----------------
float sdRoundedRect(vec2 pos, vec2 halfSize, vec4 cornerRadius) {
cornerRadius.xy = (pos.x > 0.0) ? cornerRadius.xy : cornerRadius.zw;
cornerRadius.x = (pos.y > 0.0) ? cornerRadius.x : cornerRadius.y;
vec2 q = abs(pos) - halfSize + cornerRadius.x;
return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - cornerRadius.x;
}
float boxSDF(vec2 uv) {
return sdRoundedRect(uv, size * 0.5, radius);
}
// ----------------- Blur без зерна -----------------
vec3 getBlurredColor(vec2 uv, float radius) {
vec3 col = vec3(0.0);
float total = 0.0;
const int rings = 3; // количество колец (больше = глубже размытие)
const int samples = 16; // точек на кольцо
for (int r = 1; r <= rings; r++) {
float ringRadius = radius * float(r) / float(rings);
float weightRing = exp(-0.5 * float(r)); // вес по Гауссу
for (int i = 0; i < samples; i++) {
float angle = 6.2831853 * float(i) / float(samples);
vec2 offset = vec2(cos(angle), sin(angle)) * ringRadius / InputResolution;
col += texture(InputSampler, uv + offset).rgb * weightRing;
total += weightRing;
}
}
return col / total;
}
vec3 saturate(vec3 color, float factor) {
float gray = dot(color, vec3(0.299, 0.587, 0.114));
return mix(vec3(gray), color, factor);
}
// ----------------- Refract & highlight -----------------
vec2 computeRefractOffset(float sdf) {
if (sdf < 0.1) return vec2(0.0);
vec2 grad = normalize(vec2(dFdx(sdf), dFdy(sdf)));
float offsetAmount = pow(abs(sdf), 12.0) * -0.1;
return grad * offsetAmount;
}
float highlight(float sdf) {
if (sdf < 0.1) return 0.0;
vec2 grad = normalize(vec2(dFdx(sdf), dFdy(sdf)));
return 1.0 - clamp(pow(1.0 - abs(dot(grad, vec2(-1.0, 1.0))), 0.5), 0.0, 1.0);
}
// ----------------- MAIN -----------------
void main() {
vec2 fragCoord = gl_FragCoord.xy;
vec2 centeredUV = fragCoord - (location + size * 0.5);
float sdf = boxSDF(centeredUV);
float normalizedInside = (sdf / size.y) + 1.0;
float edgeBlendFactor = pow(normalizedInside, 12.0);
vec3 baseTex = texture(InputSampler, fragCoord / InputResolution).rgb;
vec2 sampleUV = fragCoord / InputResolution + computeRefractOffset(normalizedInside);
float blurRadius = mix(6.0, 2.0, edgeBlendFactor); // увеличил радиус для мягкости
vec3 blurredTex = getBlurredColor(sampleUV, blurRadius);
blurredTex = mix(blurredTex, pow(saturate(blurredTex, 2.0), vec3(0.5)), edgeBlendFactor);
// лёгкий хайлайт внутри
blurredTex += mix(0.0, 0.5,
clamp(highlight(normalizedInside) * pow(edgeBlendFactor, 5.0), 0.0, 1.0));
// мягкая маска вместо жёсткого clamp
float boxMask = 1.0 - smoothstep(0.0, softness, sdf);
// итоговое стекло
vec3 finalGlass = mix(baseTex, blurredTex, boxMask);
// подсветка по краю
float edgeGlow = 1.0 - smoothstep(0.0, softness * 2.0, abs(sdf));
finalGlass += vec3(0.05, 0.05, 0.07) * edgeGlow;
fragColor = vec4(finalGlass, 1.0);
}