Skip to content

Commit

Permalink
raytracer: Don’t ignore emission-only surfaces.
Browse files Browse the repository at this point in the history
Part of fixing <#504>.
  • Loading branch information
kpreid committed Aug 9, 2024
1 parent 745d33c commit 3faf0a5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 5 deletions.
4 changes: 2 additions & 2 deletions all-is-cubes/src/raytracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl<D: RtBlockData> SpaceRaytracer<D> {
// Side effect: called count_step_should_stop.
}
DepthStep::Span(span) => {
debug_assert!(!span.surface.diffuse_color.fully_transparent());
debug_assert!(span.surface.visible());
state.trace_through_span(span, self);
}
DepthStep::EnterBlock {
Expand All @@ -181,7 +181,7 @@ impl<D: RtBlockData> SpaceRaytracer<D> {
block_data,
} => state.accumulator.enter_block(block_data),
EnterSurface(surface) => {
debug_assert!(!surface.diffuse_color.fully_transparent());
debug_assert!(surface.visible());
state.trace_through_surface(&surface, self);
}
}
Expand Down
19 changes: 16 additions & 3 deletions all-is-cubes/src/raytracer/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ pub(crate) struct Surface<'a, D> {
}

impl<D: RtBlockData> Surface<'_, D> {
pub(crate) fn visible(&self) -> bool {
let &Self {
block_data: _,
diffuse_color,
emission,
cube: _,
t_distance: _,
intersection_point: _,
normal: _,
} = self;
!diffuse_color.fully_transparent() || emission != Rgb::ZERO
}

/// Convert the surface and its lighting to a single RGBA value as determined by
/// the given graphics options, or [`None`] if it is invisible.
///
Expand All @@ -42,7 +55,7 @@ impl<D: RtBlockData> Surface<'_, D> {
.graphics_options
.transparency
.limit_alpha(self.diffuse_color);
if diffuse_color.fully_transparent() {
if diffuse_color.fully_transparent() && self.emission == Rgb::ZERO {
// Short-circuit if the surface has no effect.
return None;
}
Expand Down Expand Up @@ -212,7 +225,7 @@ where
Some(Evoxel {
color, emission, ..
}) => {
if color.fully_transparent() {
if color.fully_transparent() && emission == Rgb::ZERO {
// The caller could generically skip transparent, but if we do it then
// we can skip some math too.
TraceStep::Invisible {
Expand Down Expand Up @@ -285,7 +298,7 @@ where
let rc_step = self.voxel_raycaster.next()?;
let voxel = self.array.get(rc_step.cube_ahead())?;

if voxel.color.fully_transparent() {
if voxel.color.fully_transparent() && voxel.emission == Rgb::ZERO {
return Some(TraceStep::Invisible {
t_distance: rc_step.t_distance() * self.antiscale,
});
Expand Down

0 comments on commit 3faf0a5

Please sign in to comment.