-
Notifications
You must be signed in to change notification settings - Fork 3
/
final01_SSAO.fsh
190 lines (146 loc) · 6.09 KB
/
final01_SSAO.fsh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//
#version 130
uniform sampler2D sampler0;
uniform sampler2D sampler1;
uniform sampler2D sampler2;
uniform sampler2D stepSampler0;
uniform sampler2D cleanDepth;
uniform float displayWidth;
uniform float displayHeight;
uniform float aspectRatio;
uniform float near;
uniform float far;
vec4 TexCoord0 = gl_TexCoord[0];
float
getDepth (vec2 coord)
{
if (coord.x < 0.0)
coord.x = -coord.x; // should not sample outside the screen as there are no infos
if (coord.x > 1.0)
coord.x = (1.0 - coord.x) + 1.0; // Telling the shader to go back on the tex
if (coord.y < 0.0)
coord.y = -coord.y / 2.0;
if (coord.y > 1.0)
coord.y = (1.0 - coord.y) + 1.0;
float depth = texture2D (cleanDepth, coord).x;
depth = (2.0 * near) / (far + near - depth * (far - near));
return depth;
}
#ifdef SSAO_ENABLED // Stuff only SSAO uses
vec4
getSSAO ()
{
float depth = getDepth (TexCoord0.xy);
float d;
if (texture2D (sampler2, TexCoord0.xy).x < 1.0)
{
return vec4 (1.0, 1.0, 1.0, 1.0);
}
float depthN = depth;
float Rp = clamp (DISTANCE_DECAY_BEGINS, 0.0, far) / far;
float Rp2 = clamp (DISTANCE_DECAY_ENDS, 0.0, far) / far;
if (Rp > Rp2)
{
Rp = Rp2 * 0.99;
}
float depthPush = (depthN - Rp) / (Rp2 - Rp);
float ao = 0.0;
if (depthN * depthPush < 1.0)
{ // If max_distance is not reached, then go ahead
float aoCap = 1.0;
float aoMultiplier = 512.0;
float depthTolerance = 0.000015;
float displayScale = (displayWidth / 854); // scale ratio for you guys playing in fullscreen, 854 is the native width
float totalSize = EFFECT_SIZE * displayScale; // size of the ssao "envelope", modified by your resolution ( higher resolution tend to "compress" the effect )
// this is actually used to do some maths below
// in order to calculate the offset between each iteration.
float pw = (EFFECT_SIZE) / (SAMPLES * displayWidth * depth * 20); // retake on the code to allow depth to have a saying and not get
float ph = (EFFECT_SIZE) / (SAMPLES * displayHeight * depth * 20); // the exact same envelope on a near object and a far object.
#ifdef FPS_GAIN
// for( int i = 1; i <= (floor(SAMPLES*(1-(depthN*depthPush))+1)); i++ ){ // Temp code; waiting to be used for some FPS optimization - not working great yet
for (int i = 1; i <= SAMPLES + 1; i++)
{ // retake on the original code to allow more "blur"
// and more "depth" in the occlusion effect
d = getDepth (vec2 (TexCoord0.x + pw, TexCoord0.y + ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x - pw, TexCoord0.y + ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x - pw, TexCoord0.y - ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x + pw, TexCoord0.y - ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
pw *= pow ((totalSize), 1.0 / SAMPLES);
ph *= pow ((totalSize), 1.0 / SAMPLES);
aoMultiplier *= 1 - ((i - 1) / SAMPLES);
}
ao /= (SAMPLES * 3.0);
#else
// for( int i = 1; i <= (floor(SAMPLES*(1-(depthN*depthPush))+1)); i++ ){ // Temp code; waiting to be used for some FPS optimization - not working great yet
for (int i = 1; i <= SAMPLES + 1; i++)
{ // retake on the original code to allow more "blur"
// and more "depth" in the occlusion effect
d = getDepth (vec2 (TexCoord0.x + (pw * 1.5), TexCoord0.y));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x + pw, TexCoord0.y + ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x, TexCoord0.y + (ph * 1.5)));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x - pw, TexCoord0.y + ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x - (pw * 1.5), TexCoord0.y));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x - pw, TexCoord0.y - ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x, TexCoord0.y - (ph * 1.5)));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
d = getDepth (vec2 (TexCoord0.x + pw, TexCoord0.y - ph));
ao +=
min (aoCap,
max (0.0, depth - d - depthTolerance) * aoMultiplier);
pw *= pow ((totalSize), 1.0 / SAMPLES);
ph *= pow ((totalSize), 1.0 / SAMPLES);
aoMultiplier *= 1 - ((i - 1) / SAMPLES);
}
ao /= (SAMPLES * 5.0);
#endif
ao = clamp (SSAO_MULT * ao, 0.0, 1.0); // multiplicator
ao = clamp ((1 - ao) + (depthN * depthPush), 0.0, 1.0);
}
else
{ // If max_distance is reached, then ignore the long computation, and giev moar fps
ao = 1.0;
}
return vec4 (ao, ao, ao, 1.0);
}
#endif
void
main ()
{
vec4 baseColor = texture2D (sampler0, TexCoord0.st);
#ifdef SSAO_ENABLED
baseColor *= getSSAO ();
#endif
gl_FragColor = baseColor;
}