forked from lettier/3d-game-shaders-for-beginners
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssao.frag
91 lines (69 loc) · 2.04 KB
/
ssao.frag
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
/*
(C) 2019 David Lettier
lettier.com
*/
#version 140
#define NUM_SAMPLES 64
#define NUM_NOISE 16
uniform mat4 lensProjection;
uniform vec3 samples[NUM_SAMPLES];
uniform vec3 noise[NUM_NOISE];
uniform sampler2D positionTexture;
uniform sampler2D normalTexture;
uniform vec2 enabled;
out vec4 fragColor;
void main() {
float radius = 1.1;
float bias = 0.026;
float lowerRange = -2;
float upperRange = 2;
vec2 texSize = textureSize(positionTexture, 0).xy;
vec2 texCoord = gl_FragCoord.xy / texSize;
vec4 position = texture(positionTexture, texCoord);
vec3 normal = texture(normalTexture, texCoord).xyz;
int noiseX = int(gl_FragCoord.x - 0.5) % 4;
int noiseY = int(gl_FragCoord.y - 0.5) % 4;
vec3 random = noise[noiseX + (noiseY * 4)];
vec3 tangent = normalize(random - normal * dot(random, normal));
vec3 binormal = cross(normal, tangent);
mat3 tbn = mat3(tangent, binormal, normal);
float occlusion = NUM_SAMPLES;
for (int i = 0; i < NUM_SAMPLES; ++i) {
vec3 sample = tbn * samples[i];
sample = position.xyz + sample * radius;
vec4 offset = vec4(sample, 1.0);
offset = lensProjection * offset;
offset.xyz /= offset.w;
offset.xyz = offset.xyz * 0.5 + 0.5;
// Config.prc
// gl-coordinate-system default
// textures-auto-power-2 1
// textures-power-2 down
vec4 offsetPosition = texture(positionTexture, offset.xy);
float occluded = 0;
if (sample.y + bias <= offsetPosition.y) { occluded = 0; } else { occluded = 1; }
float intensity =
smoothstep
( 0.0
, 1.0
, radius
/ abs(position.y - offsetPosition.y)
);
occluded *= intensity;
occlusion -= occluded;
}
occlusion /= NUM_SAMPLES;
occlusion =
( ( (occlusion - 0)
* (upperRange - lowerRange)
)
/ (1 - 0)
)
+ lowerRange;
occlusion = clamp(occlusion, 0, 1);
if (enabled.x == 1) {
fragColor = vec4(vec3(occlusion), position.a);
} else {
fragColor = vec4(1);
}
}