veloren/assets/voxygen/shaders/include/light.glsl

78 lines
1.7 KiB
Plaintext
Raw Normal View History

struct Light {
vec4 light_pos;
vec4 light_col;
};
layout (std140)
uniform u_lights {
Light lights[32];
};
2019-09-25 12:00:00 +00:00
struct Shadow {
vec4 shadow_pos_radius;
};
layout (std140)
uniform u_shadows {
Shadow shadows[24];
};
2019-08-04 19:54:08 +00:00
#include <srgb.glsl>
vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) {
2019-09-23 19:37:50 +00:00
float avg_col = (color.r + color.g + color.b) / 3.0;
2019-10-07 08:05:18 +00:00
return ((color - avg_col) * light + (diffuse + ambience) * avg_col) * (diffuse + ambience);
2019-09-23 19:37:50 +00:00
}
2019-07-21 15:04:36 +00:00
float attenuation_strength(vec3 rpos) {
return 1.0 / (rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z);
}
vec3 light_at(vec3 wpos, vec3 wnorm) {
2019-07-29 12:00:56 +00:00
const float LIGHT_AMBIENCE = 0.025;
2019-07-21 15:04:36 +00:00
vec3 light = vec3(0);
2019-09-25 12:00:00 +00:00
for (uint i = 0u; i < light_shadow_count.x; i ++) {
2019-07-29 12:00:56 +00:00
// Only access the array once
Light L = lights[i];
2019-07-21 15:04:36 +00:00
vec3 light_pos = L.light_pos.xyz;
// Pre-calculate difference between light and fragment
vec3 difference = light_pos - wpos;
2019-09-25 12:42:56 +00:00
float strength = pow(attenuation_strength(difference), 0.6);
// Multiply the vec3 only once
2019-08-04 19:54:08 +00:00
vec3 color = srgb_to_linear(L.light_col.rgb) * (strength * L.light_col.a);
2020-01-27 01:47:23 +00:00
light += color * (max(0, dot(normalize(difference), wnorm) + 0.15) + LIGHT_AMBIENCE);
2019-07-21 15:04:36 +00:00
}
return light;
2019-09-23 19:37:50 +00:00
}
2019-09-25 12:00:00 +00:00
float shadow_at(vec3 wpos, vec3 wnorm) {
float shadow = 1.0;
for (uint i = 0u; i < light_shadow_count.y; i ++) {
// Only access the array once
Shadow S = shadows[i];
vec3 shadow_pos = S.shadow_pos_radius.xyz;
float radius = S.shadow_pos_radius.w;
vec3 diff = shadow_pos - wpos;
if (diff.z >= 0.0) {
2020-01-24 09:50:03 +00:00
diff.z = -sign(diff.z) * diff.z * 0.1;
2019-09-25 12:00:00 +00:00
}
float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), 0.5);
shadow = min(shadow, shade);
}
return min(shadow, 1.0);
}