#version 460 core // gbuffer textures uniform sampler2D s_albedo; uniform sampler2D s_depth; uniform sampler2D s_normal; uniform sampler2D s_material; uniform sampler2D s_position; // lights #define MAX_LIGHT_COUNT 100 #define POINT 0 #define SPOT 1 #define DIRECTIONAL 2 #define AMBIENT 3 struct light_t { vec3 color; vec3 position; vec3 direction; float intensity; int type; }; uniform light_t lights[MAX_LIGHT_COUNT]; uniform int light_count; uniform vec3 view_pos; // from vertex shader in vec3 pos; in vec2 tex; out vec4 FragColor; vec3 albedo; float depth; vec3 normal; vec3 material; // specular, roughness, metalic vec3 position; float specular; float roughness; float metalic; vec3 calc_light(light_t light) { vec3 light_dir = normalize(light.position - position); vec3 view_dir = normalize(view_pos - position); vec3 reflect_dir = reflect(-light_dir, normal); float diffuse = max(dot(normal, light_dir), 0.0); float specular = pow(max(dot(view_dir, reflect_dir), 0.0), 1 - roughness) * specular; return (diffuse + specular) * light.intensity * light.color / max(pow(length(light.position - position), 2), 1); } void main() { albedo = texture(s_albedo, tex).rgb; depth = texture(s_depth, tex).x; normal = (texture(s_normal, tex).rgb * 0.5) + 0.5; material = texture(s_material, tex).xyz; { specular = material.x; roughness = material.y; metalic = material.z; } position = texture(s_position, tex).xyz; vec3 light_result; for (int i = 0; i < light_count; i++) { light_result += calc_light(lights[i]); } FragColor = vec4(albedo * light_result, 1); }