87 lines
2.5 KiB
GLSL
87 lines
2.5 KiB
GLSL
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;
|
|
|
|
uniform vec3 cam_pos;
|
|
uniform sampler2D tex;
|
|
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 dir_diffuse;
|
|
uniform vec3 dir_specular;
|
|
uniform int n_lights;
|
|
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_diffuse * diff * rgb;
|
|
vec3 specular = dir_specular * 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);
|
|
vec3 rgb = texel.rgb * texel.a;
|
|
vec3 result = calc_dir_light(norm, dir, rgb);
|
|
// 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, 1.0);
|
|
}
|