RustPhysicsMQ/src/shaders/shader.frag

87 lines
3.1 KiB
GLSL
Raw Normal View History

2025-11-23 18:40:48 +00:00
#version 330 core
in vec4 v_normal;
in vec4 color;
2025-11-23 23:43:48 +00:00
in vec3 light_direction;
2025-11-28 20:39:09 +00:00
in vec4 v_light_space_position; // New: Position transformed by LightSpaceMatrix
2025-11-23 18:40:48 +00:00
uniform int render_normals_bool;
2025-11-28 20:39:09 +00:00
uniform int render_shadows_bool;
uniform sampler2D shadow_map; // New: Depth map texture
2025-11-23 18:40:48 +00:00
out vec4 FragColor;
const float ambient_strenght = 0.3;
const float diffuse_strenght = 0.7;
2025-11-28 20:39:09 +00:00
/**
* Calculates the shadow factor (0.0 for shadow, 1.0 for lit).
*/
float calculate_shadow() {
float min_bias = 0.003;
float max_bias = 0.01;
float dot_product = dot(normalize(v_normal.xyz), normalize(light_direction));
float bias = max(max_bias * (1.0 - dot_product), min_bias);
// float bias = 0;
// 1. Perspective divide to get Normalized Device Coordinates (NDC)
vec3 proj_coords = v_light_space_position.xyz / v_light_space_position.w;
// 2. Transform to texture coordinates (0 to 1 range)
vec2 tex_coords = proj_coords.xy * 0.5 + 0.5;
// 3. Get the closest depth from the light's perspective (shadow map)
// We sample the red channel since Macroquad's depth texture stores depth data there.
float closest_depth = texture(shadow_map, tex_coords).r;
// 4. Get the current fragment's depth from the light's perspective
// float current_depth = proj_coords.z;
float current_depth = proj_coords.z * 0.5 + 0.5;
// float current_depth = v_light_space_position.z;
// 5. Check if the fragment is outside the light frustum
if (tex_coords.x > 1.0 || tex_coords.x < 0.0 || tex_coords.y > 1.0 || tex_coords.y < 0.0 || current_depth > 1.0) {
return 1.0;
}
// float shadow = 0.0;
// vec2 texelSize = 1.0 / textureSize(shadow_map, 0);
// int x_ran = 1;
// for (int x = -x_ran; x <= x_ran; x++)
// {
// for (int y = -x_ran; y <= x_ran; y++)
// {
// float pcfDepth = texture(shadow_map, tex_coords + vec2(x, y) * texelSize).x;
// shadow += current_depth - bias > pcfDepth ? 0.0 : 1.0;
// }
// }
// shadow = current_depth - bias > closest_depth ? 0.0 : 1.0;
// shadow /= ((2 * x_ran) + 1) * ((2 * x_ran) + 1);
// 6. Compare depths with a bias: if current depth > closest depth, we are in shadow (0.0)
float shadow = current_depth - bias > closest_depth ? 0.0 : 1.0;
return min(max(shadow, 0), 1);
}
2025-11-23 18:40:48 +00:00
void main() {
2025-11-23 23:43:48 +00:00
float diff = max(dot(normalize(vec3(v_normal.x, v_normal.y, v_normal.z)), normalize(light_direction)), 0) * diffuse_strenght;
2025-11-28 20:39:09 +00:00
2025-11-23 18:40:48 +00:00
if (render_normals_bool == 1) {
FragColor = vec4(v_normal);
2025-11-28 20:39:09 +00:00
return;
2025-11-23 18:40:48 +00:00
}
2025-11-28 20:39:09 +00:00
if (render_shadows_bool == 1) {
float lighting = ambient_strenght + diff;
FragColor = normalize(v_normal) * lighting;
return;
2025-11-23 18:40:48 +00:00
}
2025-11-28 20:39:09 +00:00
float shadow_factor = calculate_shadow();
float lighting = ambient_strenght + diff * shadow_factor;
FragColor = normalize(abs(v_normal)) * lighting;
2025-11-23 18:40:48 +00:00
}