#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; vec2 texture_coords; float specular; float roughness; float metalic; vec3 calc_light(light_t light) { // diffuse vec3 light_dir = normalize(light.position - position); float diff = max(dot(normal, light_dir), 0); vec3 diffuse_light = diff * light.color * light.intensity; // specular float specular_strength = 0.5; vec3 view_dir = normalize(view_pos - position); vec3 reflect_dir = reflect(-light_dir, normal); float spec = pow(max(dot(view_dir, reflect_dir), 0), 32); vec3 specular_light = specular_strength * spec * light.color * light.intensity * specular; // attenuation float dist = length(light.position - position); float attenuation = 1 / max(pow(dist, 2), 1); return (diffuse_light + specular_light) * attenuation; } void main() { albedo = pow(texture(s_albedo, tex).rgb, vec3(2.2)); depth = texture(s_depth, tex).x; normal = normalize(texture(s_normal, tex).rgb); material = texture(s_material, tex).xyz; { specular = material.x; roughness = 1 - material.y; metalic = material.z; } position = texture(s_position, tex).xyz; vec3 light_result = vec3(0.1); for (int i = 0; i < light_count; i++) { light_result += calc_light(lights[i]); } FragColor = vec4(albedo * light_result, 1); }