Skip to content

Commit

Permalink
math: Add Rgba::reflect().
Browse files Browse the repository at this point in the history
  • Loading branch information
kpreid committed Oct 18, 2024
1 parent ca07163 commit b652efe
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 5 deletions.
15 changes: 15 additions & 0 deletions all-is-cubes-base/src/math/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,21 @@ impl Rgba {
alpha: self.alpha.clamp(NN0, NN1),
}
}

/// Compute the light reflected from a surface with this reflectance and alpha.
//---
// Design note: This method doesn't exist because it’s a terribly frequent pattern,
// but because when I experimented with some stronger typing of color values,
// it popped up 3 times as a needed operation, and I think there’s something notable
// there. Someday we might distinguish “RGB light” and “RGB fully-opaque surface colors”
// and then this will be important for working with definitely the former and not the latter.
#[inline]
#[doc(hidden)] // not sure if good public API
pub fn reflect(self, illumination: Rgb) -> Rgb {
// TODO: do this math without any NaN checks or negative/amplified values.
// by introducing a dedicated RgbaReflectance type with constrained components?
self.to_rgb() * illumination * self.alpha
}
}

impl From<Vector3D<NotNan<f32>, Intensity>> for Rgb {
Expand Down
2 changes: 1 addition & 1 deletion all-is-cubes-content/src/landscape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ pub(crate) fn grass_placement_function(seed: u32) -> impl Fn(Cube) -> Option<Gra

/// Sky whose lower half pretends to be a grassy plane.
pub(crate) fn sky_with_grass(sky_color: Rgb) -> Sky {
let ground = palette::GRASS * sky_color;
let ground = palette::GRASS.with_alpha_one().reflect(sky_color);
Sky::Octants([
ground, ground, sky_color, sky_color, //
ground, ground, sky_color, sky_color, //
Expand Down
3 changes: 1 addition & 2 deletions all-is-cubes/src/raytracer/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ impl<D: RtBlockData> Surface<'_, D> {

let illumination = self.compute_illumination(rt);
// Combine reflected and emitted light to produce the outgoing light.
let outgoing_rgb =
diffuse_color.to_rgb() * illumination * diffuse_color.alpha() + self.emission;
let outgoing_rgb = diffuse_color.reflect(illumination) + self.emission;

Some(ColorBuf::from_light_and_transmittance(
outgoing_rgb,
Expand Down
4 changes: 2 additions & 2 deletions all-is-cubes/src/space/light/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,9 +732,9 @@ impl LightBuffer {
let light_cube = hit.adjacent();
let stored_light = light_behind_cache.unwrap_or_else(|| current_light.get(light_cube));

let reflectance = hit_surface_color.to_rgb() * hit_alpha;
let light_from_struck_face =
ev_hit.light_emission() + stored_light.value() * reflectance;
ev_hit.light_emission() + hit_surface_color.reflect(stored_light.value());

self.incoming_light +=
light_from_struck_face * ray_state.alpha * ray_state.ray_weight_by_faces;

Expand Down

0 comments on commit b652efe

Please sign in to comment.