diff options
Diffstat (limited to 'pbr/1.1.lighting/ssao.frag')
-rw-r--r-- | pbr/1.1.lighting/ssao.frag | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/pbr/1.1.lighting/ssao.frag b/pbr/1.1.lighting/ssao.frag new file mode 100644 index 0000000..dd03754 --- /dev/null +++ b/pbr/1.1.lighting/ssao.frag @@ -0,0 +1,45 @@ +#version 330 core + +in vert_t { + vec2 tex_coords; +} vert; + +out float frag_color; + +uniform sampler2D positions; +uniform sampler2D normals; +uniform sampler2D noise; + +uniform vec3 samples[64]; +uniform mat4 projection; + +const vec2 noise_scale = vec2(1600.0 / 4.0, 900.0 / 4.0); + +void main() +{ + vec3 position = texture(positions, vert.tex_coords).rgb; + vec3 normal = texture(normals, vert.tex_coords).rgb; + vec3 random = texture(noise, vert.tex_coords * noise_scale).rgb; + + vec3 tangent = normalize(random - normal * dot(random, normal)); + vec3 bitangent = cross(normal, tangent); + mat3 TBN = mat3(tangent, bitangent, normal); + + int nsamples = 64; + float radius = 0.5; + float bias = 0.025; + float occlusion = 0.0; + for (int i = 0; i < nsamples; i++) { + vec3 sample = TBN * samples[i]; + sample = position + sample * radius; + vec4 offset = vec4(sample, 1.0); + offset = projection * offset; + offset.xyz /= offset.w; + offset.xyz = offset.xyz * 0.5 + 0.5; + float depth = texture(positions, offset.xy).z; + float range_check = smoothstep(0.0, 1.0, radius / abs(position.z - depth)); + occlusion += (depth >= sample.z + bias ? 1.0 : 0.0) * range_check; + } + occlusion = 1.0 - (occlusion / nsamples); + frag_color = occlusion; +} |