summaryrefslogtreecommitdiff
path: root/advanced_lighting/3.1.shadow_mapping/shaders/shadow.fs
blob: 1c7018a75cac3d8ba9f74487e7e5e1e6846e7092 (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
#version 330 core

in VS_OUT {
    vec4 frag_pos_light_space;
    vec3 frag_pos;
    vec3 normal;
    vec2 tex_coords;
} fs_in;

out vec4 frag_color;

uniform vec3 light_pos;
uniform vec3 view_pos;

uniform sampler2D diffuse_texture;
uniform sampler2D shadow_map;

float
calculate_shadow()
{
    vec3 proj_coords = fs_in.frag_pos_light_space.xyz/fs_in.frag_pos_light_space.w;
    proj_coords = proj_coords*0.5+0.5;
    float closest_depth = texture(shadow_map, proj_coords.xy).r;
    float current_depth = proj_coords.z;
    vec3 normal = normalize(fs_in.normal);
    vec3 light_dir = normalize(light_pos-fs_in.frag_pos);
    float bias = max(0.04*(1.0-dot(normal, light_dir)), 0.004);
    float shadow = 0;
    vec2 texel_size = 1.0/textureSize(shadow_map, 0);
    for (int x = -1; x <= 1; x++)
    {
        for (int y = -1; y <= 1; y++)
        {
            float pcf_depth = texture(shadow_map, proj_coords.xy+vec2(x, y)*texel_size).r;
            shadow += (current_depth-bias > pcf_depth) ? 1.0 : 0.0;
        }
    }
    shadow /= 9.0;

    if (proj_coords.z > 1.0)
        shadow = 0.0;
    
    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.3);

    float ambient_strength = 0.01;
    vec3 ambient = color*ambient_strength;
    
    vec3 light_dir = normalize(light_pos-fs_in.frag_pos);
    float diff = max(dot(light_dir, normal), 0.0);
    vec3 diffuse = diff*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*color;

    float shadow = calculate_shadow();
    vec3 lighting = ambient+((diffuse+specular)*(1.0-shadow)*light_color);

    float gamma = 2.2;
    lighting = pow(lighting, vec3(1.0/gamma));

    frag_color = vec4(lighting, 1.0);
}