#version 430 core in vec2 UV; out vec4 color; uniform sampler2D depthTexture; uniform sampler2D renderTexture; //layout(location = $MVP$) uniform mat4 MVP; //layout(location = $invMVP$) uniform mat4 invMVP; const float total_strength = 1.0; const float base = 0.2; const float area = 0.0075; const float falloff = 0.00005; const float radius = 0.0002; const int sampleCount = 20; const vec3 samples[20] = { vec3(0.576112, -0.307923, 0.273497), vec3(-0.239062, 0.014342, -0.512609), vec3(-0.578527, 0.692620, 0.009409), vec3(-0.496125, 0.306383, -0.508048), vec3(-0.620389, 0.266880, 0.483354), vec3(-0.478377, 0.521577, 0.611179), vec3(0.250791, 0.168587, -0.066709), vec3(0.936988, -0.118714, -0.235831), vec3(0.310220, 0.289636, 0.046191), vec3(-0.604985, 0.514587, 0.180593), vec3(0.253899, 0.730909, 0.587989), vec3(-0.097092, -0.047744, -0.110424), vec3(-0.357070, 0.877361, 0.020189), vec3(0.550173, 0.220257, -0.754331), vec3(0.574418, 0.637574, -0.445669), vec3(0.170666, -0.597387, -0.366459), vec3(0.269777, 0.234300, -0.577843), vec3(-0.702647, -0.090661, -0.628000), vec3(-0.798998, -0.013601, 0.191734),vec3(-0.229475, 0.020532, -0.938973) }; vec3 normalFromDepth(float depth, vec2 UV) { const vec2 offset1 = vec2(0.0, 0.001); const vec2 offset2 = vec2(0.001, 0.0); float depth1 = texture(depthTexture, UV + offset1).r; float depth2 = texture(depthTexture, UV + offset2).r; vec3 p1 = vec3(offset1, depth1 - depth); vec3 p2 = vec3(offset2, depth2 - depth); vec3 normal = cross(p1, p2); normal.z = -normal.z; return normalize(normal); } float rand(vec2 co){ return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } float ssao() { // Stolen from: http://theorangeduck.com/page/pure-depth-ssao float depth = texture(depthTexture, UV).r; vec3 random = vec3(rand(UV), rand(vec2(UV.x, UV.y + 1.0)), rand(vec2(UV.x + 1.0, UV.y))); vec3 position = vec3(UV, depth); vec3 normal = normalFromDepth(depth, UV); float radius_depth = radius/depth; float occlusion = 0.0; for(int i=0; i < sampleCount; i++) { vec3 ray = radius_depth * reflect(samples[i], random); vec3 hemi_ray = position + sign(dot(ray,normal)) * ray; float occ_depth = texture(depthTexture, clamp(hemi_ray.xy, vec2(0.0), vec2(1.0))).r; float difference = depth - occ_depth; occlusion += step(falloff, difference) * (1.0-smoothstep(falloff, area, difference)); } return 1.0 - total_strength * occlusion * (1.0 / float(sampleCount)); } void main() { //color = texture(renderTexture, UV).rgba; float depth = texture(depthTexture, UV).r; color = texture(renderTexture, UV).rgba; if (depth < 0.98) { color *= ssao(); } //color = vec4(vec3(depth), 1); }