Files
CDAG/Research/shaders/SSAO.frag

87 lines
2.7 KiB
GLSL

#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);
}