#version 330 core precision highp float; precision highp sampler2D; in vec4 v_normal; in vec4 color; in vec3 light_direction; in vec4 v_light_space_position; uniform int render_normals_bool; uniform int render_shadows_bool; uniform float shadow_max_bias; uniform float shadow_min_bias; uniform float shadow_fac_bias; uniform int shadow_step_size; uniform int shadow_step_count; uniform highp sampler2D shadow_map; out vec4 FragColor; const float ambient_strenght = 0.3; const float diffuse_strenght = 0.7; /** * Calculates the shadow factor (0.0 for shadow, 1.0 for lit). */ float calculate_shadow() { float cosTheta = dot(normalize(v_normal.xyz), normalize(light_direction)); float bias = shadow_fac_bias * tan(acos(cosTheta)); bias = clamp(bias, shadow_min_bias, shadow_max_bias); // float bias = max(shadow_max_bias * (1.0 - dot_product), shadow_min_bias); // 1. Perspective divide to get Normalized Device Coordinates (NDC) vec3 proj_coords = v_light_space_position.xyz / v_light_space_position.w; proj_coords = proj_coords * 0.5 + 0.5; float current_depth = proj_coords.z; // Deal with coords outside texture or infinite distance (no objects found) if (proj_coords.x > 1.0 || proj_coords.x < 0.0 || proj_coords.y > 1.0 || proj_coords.y < 0.0 || current_depth > 1.0) { return 1.0; } vec2 texelSize = 1.0 / textureSize(shadow_map, 0); float shadow = 0; int range = (shadow_step_count - 1) / 2; for (int x = -range; x <= range; x++) { for (int y = -range; y <= range; y++) { float pcfDepth = texture(shadow_map, proj_coords.xy + (vec2(x, y) * texelSize) * shadow_step_size).r; shadow += current_depth - bias > pcfDepth ? 0.0 : 1.0; } } shadow /= shadow_step_count * shadow_step_count; return shadow; } void main() { float diff = max(dot(normalize(vec3(v_normal.x, v_normal.y, v_normal.z)), normalize(light_direction)), 0) * diffuse_strenght; vec4 app_color; if (render_normals_bool == 1) { app_color = normalize(abs(v_normal)); } else { app_color = color / 256; } if (render_shadows_bool == 1) { float shadow_factor = calculate_shadow(); float lighting = ambient_strenght + diff * shadow_factor; FragColor = app_color * lighting; } else { float lighting = ambient_strenght + diff; FragColor = app_color * lighting; } }