summaryrefslogtreecommitdiff
path: root/advanced_lighting/3.2.point_shadows/shaders/shadow.fs
blob: 6a3a8b065177407a88ed0232a0c781a030c7d681 (plain)
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);
}