out vec4 FragColor; struct light_t { vec4 position; vec4 ambient; // constant vec4 diffuse; // linear vec4 specular; // quadratic vec4 range; }; in vec3 vertex; in vec3 normal; in vec2 tex_coord; in vec2 lm_coord; in float brightness; uniform vec3 cam_pos; uniform sampler2D tex; uniform sampler2D lightmap; uniform vec3 specular; uniform float shine; uniform float max_vert_dist; uniform float max_cam_dist; uniform float light_factor; uniform vec3 dir_direction; uniform vec3 dir_ambient; uniform vec3 block_ambient; uniform int n_lights; uniform bool sky_light; uniform light_block { light_t lights[MAX_LIGHTS]; }; /* vec4 pcf_sample(sampler2D stex, vec2 pos) { vec4 avg = vec4(0.0); vec2 texel = 1.0 / textureSize(stex, 0); for(int x = -1; x <= 1; x++) { for(int y = -1; y <= 1; y++) { avg += texture(stex, pos + vec2(x, y) * texel); } } return avg /= 9.0; } */ vec3 calc_dir_light(vec3 norm, vec3 dir, vec3 rgb) { vec3 ldir = normalize(-dir_direction); float diff = max(dot(norm, ldir), 0.0); vec3 rdir = reflect(-ldir, norm); float spec = pow(max(dot(dir, rdir), 0.0), shine); vec3 ambient = dir_ambient * rgb + clamp(vec3(0.0), 0.0, 1.0); vec3 diffuse = dir_ambient * 0.125 * diff * rgb; vec3 specular = dir_ambient * 1.25 * spec * specular * rgb; return (ambient + diffuse + specular); } vec3 calc_point_light(light_t light, vec3 norm, vec3 dir, vec3 rgb) { rgb = clamp(rgb + light_factor, 0.0, 1.0); vec3 ldir = normalize(light.position.xyz - vertex); float diff = max(dot(norm, ldir), 0.0); vec3 rdir = reflect(-ldir, norm); float spec = pow(max(dot(dir, rdir), 0.0), shine); float distance = length((light.position.xyz - vertex) / light.range.xyz); float attenuation = 1.0 / (light.ambient.w + light.diffuse.w * distance + light.specular.w * (distance * distance)); vec3 ambient = light.ambient.xyz * rgb; vec3 diffuse = light.diffuse.xyz * diff * rgb; vec3 specular = light.specular.xyz * spec * specular * rgb; ambient *= attenuation; diffuse *= attenuation; specular *= attenuation; return (ambient + diffuse + specular); } void main() { vec3 norm = normalize(normal); vec3 dir = normalize(cam_pos - vertex); vec4 texel = texture(tex, tex_coord); float sky = sky_light ? vertex.y < 0.0 ? 0.0 : (vertex.y < 64.0 ? vertex.y / 64.0 : 1.0) : 1.0; float block = clamp(0.03125 + lm_coord.x * 256.0, 0.0, 1.0); vec3 lm = block * block_ambient; vec3 rgb = texel.rgb; // * brightness; vec3 result = rgb * lm + calc_dir_light(norm, dir, rgb * sky * (1.0 - block)); // int l = 0; for(int z = 0; z < n_lights; z++) { // if(lights[z].enabled) { if(distance(vertex, lights[z].position.xyz) <= max_vert_dist && distance(cam_pos, lights[z].position.xyz) <= max_cam_dist) result += calc_point_light(lights[z], norm, dir, rgb); // l++; // } } FragColor = vec4(result, texel.a); }