mat4 vertex_tf = get_vertex_transform();
mat3 normal_tf = get_normal_transform();
- vec4 world_vertex = vertex_tf*get_vertex_position();
+ out vec4 world_vertex = vertex_tf*get_vertex_position();
vec4 eye_vertex = eye_world_matrix*world_vertex;
gl_Position = clip_eye_matrix*eye_vertex;
vec3 eye_pos = (inverse(eye_world_matrix)*vec4(0.0, 0.0, 0.0, 1.0)).xyz;
out vec3 world_look_dir = normalize(world_vertex.xyz-eye_pos);
- out vec3 world_light_dir = light_sources[0].position.xyz-world_vertex.xyz*light_sources[0].position.w;
-
out float fog_coord = eye_vertex.z;
if(use_clipping)
return normalize(world_normal);
}
+virtual vec3 get_light_direction(int index)
+{
+ vec4 light_pos = light_sources[index].position;
+ return normalize(light_pos.xyz-world_vertex.xyz*light_pos.w);
+}
+
virtual vec3 get_environment_sample(vec3 direction, float roughness)
{
float lod = (2-roughness)*roughness*(textureQueryLevels(environment_map)-1);
vec3 cooktorrance_lighting(vec3 normal, vec3 look, vec3 base_color, float metalness, float roughness)
{
- vec3 light = normalize(world_light_dir);
-
- float shadow = get_shadow_factor(0);
- vec3 color = cooktorrance_one_light_direct(normal, look, light, light_sources[0].color, base_color, metalness, roughness)*shadow;
+ vec3 color = vec3(0.0);
+ for(int i=0; i<max_lights; ++i)
+ if(light_sources[i].enabled!=0)
+ {
+ vec3 light = get_light_direction(i);
+ float shadow = get_shadow_factor(i);
+ color += cooktorrance_one_light_direct(normal, look, light, light_sources[i].color, base_color, metalness, roughness)*shadow;
+ }
color += cooktorrance_environment(normal, look, base_color, metalness, roughness);
{
vec4 position;
vec3 color;
+ int enabled;
};
struct ClipPlane
mat4 eye_clip_matrix;
};
+layout(constant_id=auto) const int max_lights = 4;
uniform Lighting
{
- // Declared as an array for compatibility reasons
- LightSourceParameters light_sources[1];
+ LightSourceParameters light_sources[max_lights];
vec4 ambient_color;
vec4 fog_color;
float fog_density;
vec3 phong_lighting(vec3 normal, vec3 look, vec3 surface_diffuse, vec3 surface_specular, float shininess)
{
- vec3 light = normalize(world_light_dir);
-
vec3 color = phong_ambient(surface_diffuse);
- float shadow = get_shadow_factor(0);
- color += phong_one_light(light, normal, look, light_sources[0].color, surface_diffuse, surface_specular, shininess)*shadow;
+ for(int i=0; i<max_lights; ++i)
+ if(light_sources[i].enabled!=0)
+ {
+ vec3 light = get_light_direction(i);
+ float shadow = get_shadow_factor(i);
+ color += phong_one_light(light, normal, look, light_sources[i].color, surface_diffuse, surface_specular, shininess)*shadow;
+ }
if(use_emission)
color += get_emission_color();
{
if(use_shadow_map)
{
- if(shadow_coord.x<0 || shadow_coord.x>1 || shadow_coord.y<0 || shadow_coord.y>1)
+ if(index>0 || shadow_coord.x<0 || shadow_coord.x>1 || shadow_coord.y<0 || shadow_coord.y>1)
return 1.0;
float shadow_sample = texture(shadow_map, shadow_coord);
return mix(1.0, shadow_sample, shadow_darkness);
set_ambient(0.2f);
set_fog_color(Color(0.0f, 0.0f, 0.0f, 0.0f));
set_fog_density(0.0f);
+
+ for(unsigned i=0; i<8; ++i)
+ {
+ string base = format("light_sources[%d]", i);
+ shdata.uniform(base+".position", Vector4(0, 0, 1, 0));
+ shdata.uniform(base+".color", 0.0f, 0.0f, 0.0f);
+ shdata.uniform(base+".enabled", 0);
+ }
}
void Lighting::set_ambient(const Color &a)
{
auto i = find_member(lights, &l, &AttachedLight::light);
if(i!=lights.end())
+ {
lights.erase(i);
+ shdata.uniform(format("light_sources[%d].enabled", lights.size()), 0);
+ }
}
const ProgramData &Lighting::get_shader_data() const