Skip to content

Commit

Permalink
add directional light, move lightpos transform to cpu
Browse files Browse the repository at this point in the history
  • Loading branch information
ffreyer committed Sep 21, 2023
1 parent 32c01e4 commit 0e81e35
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 43 deletions.
51 changes: 27 additions & 24 deletions GLMakie/assets/shader/lighting.frag
Expand Up @@ -31,21 +31,27 @@ uniform mat4 view;
in vec3 o_camdir;
in vec3 o_view_pos;

vec3 illuminate_pointlight(int idx, vec3 normal, vec3 camera_direction, vec3 color) {
// calculate light direction and distance
vec3 light_vec = (view * vec4(light_positions[idx], 1)).xyz - o_view_pos;
float dist = length(light_vec);
vec3 light_dir = normalize(light_vec);

// diffuse coefficient (how directly does light hit the surface)
vec3 blinn_phong(vec3 light_color, vec3 normal, vec3 light_dir, vec3 color) {
// diffuse coefficient (how directly does light hits the surface)
float diff_coeff = max(dot(light_dir, normal), 0.0);

// specular coefficient (does reflected light bounce into camera)
vec3 H = normalize(light_dir + camera_direction);
// specular coefficient (does reflected light bounce into camera?)
vec3 H = normalize(light_dir + o_camdir);
float spec_coeff = pow(max(dot(H, normal), 0.0), shininess);
if (diff_coeff <= 0.0 || isnan(spec_coeff))
spec_coeff = 0.0;

return light_color * vec3(diffuse * diff_coeff * color + specular * spec_coeff);
}

vec3 calc_point_light(int idx, vec3 normal, vec3 color) {
// calculate light direction and distance
// vec3 light_vec = (view * vec4(light_positions[idx], 1)).xyz - o_view_pos;
vec3 light_vec = light_positions[idx] - o_view_pos;

float dist = length(light_vec);
vec3 light_dir = normalize(light_vec);

// How weak has the light gotten due to distance
float attentuation = 1.0;
// float attentuation = 1.0 / (
Expand All @@ -54,19 +60,16 @@ vec3 illuminate_pointlight(int idx, vec3 normal, vec3 camera_direction, vec3 col
// light_parameters[idx].z * dist * dist
// );

// final lighting model
return attentuation * blinn_phong(light_colors[idx], normal, light_dir, color);
}

return attentuation * light_colors[idx] * vec3(
diffuse * diff_coeff * color +
specular * spec_coeff
);
vec3 calc_directional_light(int idx, vec3 normal, vec3 color) {
// TODO: don't calculate view * light_direction for each pixel
// vec3 light_dir = normalize((view * vec4(light_directions[idx], 1)).xyz);
vec3 light_dir = light_directions[idx];
return blinn_phong(light_colors[idx], normal, light_dir, color);
}

// vec3 illuminate_directionallight(Light light, vec3 normal, vec3 light_direction, vec3 camera_direction, vec3 color) {
// // light coming down (0, -1, 0) should reflect off of normals (0, 1, 0) the strongest
// float diff_coeff = max(dot(-light.direction, normal), 0.0);
// return diffuse * diff_coeff * light.color * color;
// }

vec3 illuminate(vec3 normal, vec3 base_color) {
vec3 final_color = vec3(0);
Expand All @@ -76,14 +79,14 @@ vec3 illuminate(vec3 normal, vec3 base_color) {
final_color += light_colors[i] * base_color;
break;
case PointLight:
final_color += illuminate_pointlight(i, normal, o_camdir, base_color);
final_color += calc_point_light(i, normal, base_color);
break;
case DirectionalLight:
final_color += calc_directional_light(i, normal, base_color);
break;
// case DirectionalLight:
// return illuminate_directionallight(light, normal, light_direction, camera_direction, base_color);
default:
final_color += vec3(1,0,1); // debug magenta
return vec3(1,0,1); // debug magenta
}
}
return final_color;
}

34 changes: 15 additions & 19 deletions GLMakie/src/drawing_primitives.jl
Expand Up @@ -5,7 +5,7 @@ using Makie: convert_arguments
# TODO: Maybe move this somewhere else?
# TODO: observable
function handle_lights(attr::Dict, lights::Vector{Makie.AbstractLight})
maxlength = 8
maxlength = 64

if length(lights) > maxlength
@warn "GLMakie only allows up to $maxlength lights."
Expand All @@ -14,12 +14,20 @@ function handle_lights(attr::Dict, lights::Vector{Makie.AbstractLight})

attr[:light_types] = Int32.(Makie.light_type.(lights))
attr[:light_colors] = RGBf.(Makie.light_color.(lights))
attr[:light_positions] = Vec3f.(Makie.light_position.(lights))
attr[:light_directions] = Vec3f.(Makie.light_direction.(lights))
attr[:light_positions] = map(attr[:view]) do view
map(Makie.light_position.(lights)) do p
p4d = view * to_ndim(Point4f, p, 1)
return Vec3f(p4d[1] / p4d[4], p4d[2] / p4d[4], p4d[3] / p4d[4])
end
end
normalview = map(view -> transpose(inv(view[Vec(1,2,3), Vec(1,2,3)])), attr[:view])
attr[:light_directions] = map(normalview) do nv
map(p -> nv * p, Makie.light_direction.(lights))
end
attr[:light_parameters] = Vec3f.(Makie.light_parameters.(lights))

attr[:lights_length] = length(lights)
# @info "Inserted $N lights."
@info "Inserted $(length(lights)) lights."
return attr
end

Expand Down Expand Up @@ -139,26 +147,14 @@ function cached_robj!(robj_func, screen, scene, x::AbstractPlot)
gl_key => gl_value
end)

# pointlight = Makie.get_point_light(scene)
# if !isnothing(pointlight)
# @info "Set light position"
# gl_attributes[:lightposition] = pointlight.position
# end

# ambientlight = Makie.get_ambient_light(scene)
# if !isnothing(ambientlight)
# @info "Set ambient light"
# gl_attributes[:ambient] = ambientlight.color
# end

# TODO:
handle_lights(gl_attributes, scene.lights)

gl_attributes[:track_updates] = screen.config.render_on_demand

handle_intensities!(gl_attributes, x)
connect_camera!(x, gl_attributes, scene.camera, get_space(x))

# TODO:
handle_lights(gl_attributes, scene.lights)

robj = robj_func(gl_attributes)

get!(gl_attributes, :ssao, Observable(false))
Expand Down

0 comments on commit 0e81e35

Please sign in to comment.