#version 430 layout (binding = 0) uniform sampler2D depthSamp; const float minVariance = 4.096e-06; const float cutoff = 0.998; in vec4 varShadowPosition; out vec4 color; float chebyshevUpperBound(vec2 moments, float t) { float variance = moments.y - (moments.x * moments.x); variance = max(variance, minVariance); float d = t - moments.x; float pMax = variance / (variance + d * d); return max(pMax, float(t < moments.x)); } float linstep(float from, float to, float v) { return clamp((v - from) / (to - from), 0.0, 1.0); } float reduceLightBleeding(float light, float Amount) { return linstep(Amount, 1.0, light); } float getShadow(vec2 varTex, float distanceToLight) { vec2 Moments = texture(depthSamp, varTex).xy; return reduceLightBleeding(chebyshevUpperBound(Moments, distanceToLight), cutoff); } void main(void) { vec3 pos = varShadowPosition.xyz / varShadowPosition.w; float shadow = getShadow(pos.xy, pos.z); shadow = shadow * 0.6 + 0.4; color = vec4(0.8, 0.8, 0.8, 1.0) * shadow; }