#version 330 core in vec3 frag_pos; in vec3 frag_normal; in vec2 frag_uv; out vec4 color; uniform sampler2D sampler; const uint NUM_LIGHTS = 32u; layout (std140) uniform lights { uint max_p_lights; uint active_p_lights; uint max_d_lights; uint active_d_lights; uint padding; vec4 ambient_color; vec4 pl_positions[NUM_LIGHTS]; vec4 pl_colors[NUM_LIGHTS]; uint pl_intensities[NUM_LIGHTS]; // NOTE: 16 bytes * NUM_LIGHTS vec4 dl_directions[NUM_LIGHTS]; vec4 dl_colors[NUM_LIGHTS]; uint dl_intensities[NUM_LIGHTS]; // NOTE: 16 bytes * NUM_LIGHTS }; const float CONSTANT_ATTENUATION = 0.1; const float LINEAR_ATTENUATION = 0.2; const float QUADRATIC_ATTENUATION = 0.02; void main() { vec4 diffuse_color = vec4(0); // NOTE: directional lights for (uint i = 0u; i < active_d_lights; i++) { vec4 light_direction = normalize(dl_directions[i]); float diffuse_factor = clamp(dot(vec4(frag_normal, 1), light_direction), 0, 1); diffuse_color = diffuse_color + dl_intensities[i] * diffuse_factor * dl_colors[i]; } // NOTE: point lights for (uint i = 0u; i < active_p_lights; i ++) { vec3 direction = vec3(pl_positions[i]).xyz - frag_pos; float distance = length(direction); direction = direction / distance; float attenuation = CONSTANT_ATTENUATION + LINEAR_ATTENUATION * distance + QUADRATIC_ATTENUATION * pow(distance, 2); float diffuse_factor = clamp(dot(frag_normal, direction), 0, 1); vec4 added_color = pl_colors[i] * pl_intensities[i] * diffuse_factor / attenuation; diffuse_color = diffuse_color + added_color; } color = (ambient_color + diffuse_color) * texture(sampler, frag_uv.st); }