R2 Shaders
R2SSAO.frag
Go to the documentation of this file.
1 /// \file R2SSAO.frag
2 /// \brief Fragment shader for calculating an ambient occlusion term
3 
4 #include "R2GBufferInput.h"
5 #include "R2LogDepth.h"
6 #include "R2Normals.h"
8 #include "R2Viewport.h"
9 
10 uniform R2_view_rays_t R2_view_rays;
11 uniform R2_gbuffer_input_t R2_gbuffer;
12 uniform float R2_depth_coefficient;
13 
14 uniform mat4x4 R2_ssao_transform_projection;
15 uniform sampler2D R2_ssao_noise;
16 uniform vec2 R2_ssao_noise_uv_scale;
17 uniform vec3 R2_ssao_kernel[128];
18 uniform int R2_ssao_kernel_size;
19 uniform float R2_ssao_sample_radius;
20 uniform float R2_ssao_power;
21 
22 layout(location = 0) out float R2_out_occlusion;
23 
24 in vec2 R2_uv;
25 
26 void
27 main (void)
28 {
29  vec2 screen_uv = R2_uv;
30 
31  // Reconstruct the eye-space Z from the depth texture
32  float log_depth =
33  texture (R2_gbuffer.depth, screen_uv).x;
34  float eye_z_positive =
35  R2_logDepthDecode (log_depth, R2_depth_coefficient);
36  float eye_z =
37  -eye_z_positive;
38 
39  // Reconstruct the full eye-space position
40  vec4 eye_position =
41  R2_positionReconstructFromEyeZ (eye_z, screen_uv, R2_view_rays);
42 
43  // Sample normals
44  vec2 normal_compressed =
45  texture (R2_gbuffer.normal, screen_uv).xy;
46  vec3 normal =
47  R2_normalsDecompress (normal_compressed);
48 
49  // Tile the noise texture across the screen
50  vec2 noise_uv =
51  screen_uv * R2_ssao_noise_uv_scale;
52  // Sample a vector used to peturb the sampling hemisphere
53  vec3 noise_sample =
54  (texture(R2_ssao_noise, noise_uv).rgb * 2.0) - 1.0;
55 
56  // Construct a matrix used to transform the sampling hemisphere
57  vec3 tangent = normalize (noise_sample - normal * dot (noise_sample, normal));
58  vec3 bitangent = cross (normal, tangent);
59  mat3x3 m_hemi = mat3x3 (tangent, bitangent, normal);
60 
61  // Calculate occlusion for the kernel
62  float occlusion = 0.0;
63  for (int index = 0; index < R2_ssao_kernel_size; ++index) {
64  // Determine the eye-space position of the sample
65  vec3 sample_eye = ((m_hemi * R2_ssao_kernel[index]) * R2_ssao_sample_radius) + eye_position.xyz;
66 
67  // Project the eye-space sample position to clip-space
68  vec4 sample_hom = vec4 (sample_eye, 1.0);
69  vec4 sample_clip = R2_ssao_transform_projection * sample_hom;
70 
71  // Transform the clip-space sample position to UV coordinates
72  vec2 sample_ndc = sample_clip.xy / sample_clip.w;
73  vec2 sample_uv = (sample_ndc * 0.5) + 0.5;
74 
75  // Sample the depth buffer at the sample position
76  float sample_surface_depth_log =
77  texture (R2_gbuffer.depth, sample_uv).r;
78 
79  // Transform logarithmic depth to linear eye-space Z
80  float sample_surface_eye_z_positive =
81  R2_logDepthDecode (sample_surface_depth_log, R2_depth_coefficient);
82  float sample_surface_eye_z =
83  -sample_surface_eye_z_positive;
84 
85  // Exclude anything from outside of the sample radius
86  float sample_range_check =
87  abs (eye_position.z - sample_surface_eye_z) < R2_ssao_sample_radius ? 1.0 : 0.0;
88 
89  // If the surface being sampled is in front of the sample
90  // position, then the sample position is inside the geometry
91  // and therefore contributes to the occlusion.
92  //
93  // Note that this check is dependent on coordinate system handedness:
94  // Values closer to the viewer have a LARGER eye-space Z.
95  occlusion += (sample_surface_eye_z >= sample_eye.z ? 1.0 : 0.0) * sample_range_check;
96  }
97 
98  // Invert and normalize occlusion
99  occlusion = 1.0 - (occlusion / R2_ssao_kernel_size);
100 
101  // Raise the occlusion to the given exponent, to optionally
102  // add contrast.
103  occlusion = pow (occlusion, R2_ssao_power);
104 
105  R2_out_occlusion = occlusion;
106 }
sampler2D normal
The normal texture containing compressed normals (see R2_normalsDecompress).
Functions for transforming normal vectors.
Viewport types and functions.
sampler2D depth
The logarithmic depth texture (see R2_logDepthDecode).
float R2_logDepthDecode(const float z, const float depth_coefficient)
Definition: R2LogDepth.h:72
The textures that make up the G-Buffer.
A type representing the set of bound textures that make up the G-Buffer.
Definition: R2GBufferInput.h:9
vec3 R2_normalsDecompress(const vec2 n)
Definition: R2Normals.h:34
The type of view rays used to reconstruct positions during deferred rendering.
Definition: R2ViewRays.h:9
Logarithmic depth functions.
vec4 R2_positionReconstructFromEyeZ(const float eye_z, const vec2 uv, const R2_view_rays_t view_rays)
layout(location=0) out vec4 R2_out
RGBA color.
Functions for performing position reconstruction during deferred rendering.