Analytical lights
Analytical lighting in real-time rendering refers to the use of mathematical models to simulate the effects of light on surfaces.
What that means in renderling
is that analytical lights are the lights that
you create, configure and place programmatically, one by one, into the scene.
To do any lighting, though, we have to turn lighting back on in the stage:
stage.set_has_lighting(true);
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().await.unwrap();
img.save("lighting/no-lights.png").unwrap();
frame.present();
As we talked about in the GLTF example, with no lights on the stage, the bust renders in shadow.
Now we're ready to add some lights.
Directional lights
Directional lights simulate light coming from a specific direction, like sunlight. They affect all objects in the scene equally, regardless of their position, and do not diminish with distance. This makes them ideal for simulating large-scale lighting effects.
Let's create a directional light:
use renderling::{
color::css_srgb_color_to_linear,
light::{AnalyticalLight, DirectionalLight, Lux},
};
let sunset_amber_sunlight_color = css_srgb_color_to_linear(250, 198, 104);
let directional: AnalyticalLight<DirectionalLight> = stage
.new_directional_light()
.with_direction(Vec3::new(-0.5, -0.5, 0.0))
.with_color(sunset_amber_sunlight_color)
.with_intensity(Lux::OUTDOOR_OVERCAST_HIGH);
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().await.unwrap();
img.save("lighting/directional.png").unwrap();
frame.present();
Not bad!
Before moving on we'll remove the directional light:
stage.remove_light(&directional);
drop(directional);
Dropping the light isn't strictly necessary, except to reclaim the resources.
Point lights
Point lights emit light equally in all directions from a single point in space, similar to a light bulb. They are ideal for simulating localized light sources and their intensity diminishes with distance, following the inverse square law. This makes them suitable for creating realistic lighting effects in small areas.
Let's create a point light:
use renderling::light::{Candela, PointLight};
let point: AnalyticalLight<PointLight> = stage
.new_point_light()
.with_position({
let bust_aabb = model.bounding_volume().unwrap();
bust_aabb.max
})
.with_color(sunset_amber_sunlight_color)
.with_intensity(Candela(100.0));
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().await.unwrap();
img.save("lighting/point.png").unwrap();
frame.present();
Similarly we'll remove the point light before moving on:
stage.remove_light(&point);
drop(point);
Spot lights
Spot lights emit a cone of light from a single point, with a specified direction and angle. They are useful for highlighting specific areas or objects in a scene, such as a spotlight on a stage. The intensity of a spotlight diminishes with distance and is also affected by the angle of the cone, allowing for precise control over the lighting effect.
Let's create a spotlight. One thing about spotlights though, they can be a bit fiddly due to having a position, direction and inner and outer cutoff values. For this reason we'll place the spotlight at the camera's position and point it in the same direction, so you can see the effect:
use renderling::light::SpotLight;
let camera_eye = Vec3::new(0.5, 0.5, 0.8);
let camera_target = Vec3::new(0.0, 0.3, 0.0);
let position = camera_eye;
let direction = camera_target - camera_eye;
let spot: AnalyticalLight<SpotLight> = stage
.new_spot_light()
.with_position(position)
.with_direction(direction)
// the cutoff values determine the angle of the cone
.with_inner_cutoff(0.15)
.with_outer_cutoff(0.2)
.with_color(sunset_amber_sunlight_color)
.with_intensity(Candela(12_000.0));
let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().await.unwrap();
img.save("lighting/spot.png").unwrap();
frame.present();
Good enough! Now on to image-based lighting, which uses environment maps to simulate complex lighting scenarios. This technique captures real-world lighting conditions and applies them to the scene, providing more realistic reflections and ambient lighting.