#version 330 core in vec2 vTex; out vec4 FragColor; uniform sampler2D occlusionTex; uniform vec2 lightScreenPos; // in [0,1] uniform vec3 sunColor; uniform float sunIntensity; uniform float globalIntensity; uniform int samples; uniform float density; uniform float weight; uniform float decay; void main() { vec2 texCoord = vTex; // vector from current pixel to light vec2 delta = lightScreenPos - texCoord; float dist = length(delta); vec2 stepv = delta * (1.0 / float(samples)) * density; vec3 illumination = vec3(0.0); float illumDecay = 1.0; vec2 coord = texCoord; for (int i = 0; i < samples; ++i) { coord += stepv; vec3 sample = texture(occlusionTex, coord).rgb; // occlusion tex stores white where geometry present float occ = sample.r; illumination += occ * illumDecay * weight; illumDecay *= decay; } vec3 result = illumination * sunColor * sunIntensity * globalIntensity; // tone-map / clamp to avoid extreme brightness result = clamp(result, vec3(0.0), vec3(1.0)); // use luminance as alpha so we can composite less aggressively float lum = dot(result, vec3(0.299, 0.587, 0.114)); float alpha = clamp(lum, 0.0, 1.0); FragColor = vec4(result, alpha); }