R2 Core 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"
7 #include "R2PositionReconstruction.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 }
R2_gbuffer_input_t::normal
sampler2D normal
The normal texture containing compressed normals (see R2_normalsDecompress).
Definition: R2GBufferInput.h:13
layout
layout(location=0) in vec3 R2_vertex_world_position
World-space position.
R2Normals.h
Functions for transforming normal vectors.
R2Viewport.h
Viewport types and functions.
R2_gbuffer_input_t::depth
sampler2D depth
The logarithmic depth texture (see R2_logDepthDecode).
Definition: R2GBufferInput.h:17
R2_logDepthDecode
float R2_logDepthDecode(const float z, const float depth_coefficient)
Definition: R2LogDepth.h:72
R2GBufferInput.h
The textures that make up the G-Buffer.
R2_gbuffer_input_t
A type representing the set of bound textures that make up the G-Buffer.
Definition: R2GBufferInput.h:9
R2_normalsDecompress
vec3 R2_normalsDecompress(const vec2 n)
Definition: R2Normals.h:34
R2_view_rays_t
The type of view rays used to reconstruct positions during deferred rendering.
Definition: R2ViewRays.h:9
R2LogDepth.h
Logarithmic depth functions.
R2_positionReconstructFromEyeZ
vec4 R2_positionReconstructFromEyeZ(const float eye_z, const vec2 uv, const R2_view_rays_t view_rays)
Definition: R2PositionReconstruction.h:19
R2PositionReconstruction.h
Functions for performing position reconstruction during deferred rendering.