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
|
#version 330 core
in VS_OUT {
vec3 frag_pos;
vec3 normal;
vec2 tex_coords;
} fs_in;
out vec4 frag_color;
uniform vec3 light_pos;
uniform vec3 view_pos;
uniform float far;
uniform sampler2D diffuse_texture;
uniform samplerCube depth_cubemap;
vec3 grid_sampling_disk[20] = vec3[]
(
vec3(1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3(1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
vec3(1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3(1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
vec3(0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
);
float
calculate_shadow(vec3 frag_pos)
{
vec3 frag_to_light = frag_pos-light_pos;
/* float closest_depth = texture(depth_cubemap, frag_to_light).r; */
/* closest_depth *= far; */
float current_depth = length(frag_to_light);
/* float bias = 0.05; */
/* float shadow = current_depth-bias > closest_depth ? 1.0 : 0.0; */
/* NOTE(pryazha): Display depth value for debugging */
/* frag_color = vec4(vec3(closest_depth/far), 1.0); */
/*
float shadow = 0.0;
float offset = 0.1;
float samples = 4.0;
for (float x = -offset;
x < offset;
x += offset/(samples*0.5))
{
for (float y = -offset;
y < offset;
y += offset/(samples*0.5))
{
for (float z = -offset;
z < offset;
z += offset/(samples*0.5))
{
float closest_depth = texture(depth_cubemap, frag_to_light+vec3(x, y, z)).r;
closest_depth *= far;
if (current_depth-bias > closest_depth)
shadow += 1.0;
}
}
}
shadow /= (samples*samples*samples);
*/
float shadow = 0.0;
float bias = 0.15;
int samples = 20;
float view_distance = length(view_pos-frag_pos);
float disk_radius = (1.0+(view_distance/far))/25.0;
for (int sample = 0;
sample < samples;
++sample)
{
float closest_depth = texture(depth_cubemap, frag_to_light+
grid_sampling_disk[sample]*disk_radius).r;
closest_depth *= far;
if (current_depth-bias > closest_depth)
shadow += 1.0;
}
shadow /= float(samples);
return(shadow);
}
void
main(void)
{
vec3 color = texture(diffuse_texture, fs_in.tex_coords).rgb;
vec3 normal = normalize(fs_in.normal);
vec3 light_color = vec3(0.5);
vec3 ambient = 0.5*light_color;
vec3 light_dir = normalize(light_pos-fs_in.frag_pos);
float diff = max(dot(light_dir, normal), 0.0);
vec3 diffuse = diff*light_color;
vec3 view_dir = normalize(view_pos-fs_in.frag_pos);
vec3 halfway_dir = normalize(light_dir+view_dir);
float spec = pow(max(dot(halfway_dir, normal), 0.0), 64.0);
vec3 specular = spec*light_color;
float shadow = calculate_shadow(fs_in.frag_pos);
vec3 lighting = (ambient+(1.0-shadow)*(diffuse+specular))*color;
frag_color = vec4(lighting, 1.0);
}
|