#version 330 core in vert_t { vec2 tex_coords; } vert; out vec4 frag_color; uniform sampler2D positions; uniform sampler2D normals; uniform sampler2D color_specular; uniform vec3 view_position; struct light_t { vec3 position; vec3 color; }; const int light_count = 200; uniform light_t lights[light_count]; const float linear = 0.7f; const float quadratic = 1.8f; void main() { vec3 position = texture(positions, vert.tex_coords).rgb; vec3 normal = texture(normals, vert.tex_coords).rgb; vec3 color = texture(color_specular, vert.tex_coords).rgb; float specular = texture(color_specular, vert.tex_coords).a; vec3 ambient = 0.1 * color; vec3 view_dir = normalize(view_position - position); vec3 result = ambient; for (int i = 0; i < light_count; i++) { vec3 light_dir = normalize(lights[i].position - position); vec3 diffuse = max(dot(normal, light_dir), 0.0) * color * lights[i].color; float distance = length(lights[i].position - position); float attenuation = 1.0 / (1.0 + linear * distance + quadratic * distance * distance); vec3 halfway_dir = normalize(view_dir + light_dir); vec3 specular = pow(max(dot(halfway_dir, normal), 0.0), 32.0) * vec3(0.5); result += (diffuse + specular) * attenuation; } frag_color = vec4(result, 1.0); }