Skip to content

Commit

Permalink
camera: Replace use_frustum_culling option with `debug_reduce_view_…
Browse files Browse the repository at this point in the history
…frustum`.

“Should we use frustum culling” is not particularly in doubt; this
replacement option lets us test the accuracy of the culling by effectively
revealing what is drawn past the bounds of the viewport.
  • Loading branch information
kpreid committed Dec 27, 2024
1 parent ba53757 commit a11611b
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 30 deletions.
14 changes: 13 additions & 1 deletion all-is-cubes-gpu/src/in_wgpu/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use all_is_cubes::content::palette;
use all_is_cubes::listen::{self, Listen as _, Listener};
use all_is_cubes::math::{
rgba_const, Cube, Face6, FreeCoordinate, FreePoint, GridAab, GridCoordinate, GridPoint,
GridSize, GridVector, Rgb, Wireframe as _, ZeroOne,
GridSize, GridVector, Rgb, Rgba, Wireframe as _, ZeroOne,
};
use all_is_cubes::raycast::Ray;
#[cfg(feature = "rerun")]
Expand Down Expand Up @@ -726,6 +726,18 @@ impl<I: time::Instant> SpaceRenderer<I> {
return;
};

if camera.options().debug_reduce_view_frustum {
// Draw the modified view frustum, which becomes a viewport box in screen space.
// (Note the lines are at risk of being clipped, but in practice are sufficiently
// visible but flickery.)
camera
.view_frustum_geometry()
.wireframe_points(&mut crate::map_line_vertices::<WgpuLinesVertex>(
v,
Rgba::WHITE,
));
}

if camera.options().debug_chunk_boxes {
let view_chunk = csm.view_chunk();

Expand Down
15 changes: 6 additions & 9 deletions all-is-cubes-mesh/src/dynamic/chunked_mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,14 @@ where
.chunks(self.view_chunk(), camera.view_direction_mask())
.filter_map(|pos| {
let chunk = self.chunk(pos)?;
let use_frustum_culling = camera.options().use_frustum_culling;
let item = InViewChunkRef {
chunk,
mesh_in_view: !use_frustum_culling
|| chunk
.mesh_bounding_box()
.is_some_and(|bb| camera.aab_in_view(bb)),
instances_in_view: !use_frustum_culling
|| chunk
.block_instances_bounding_box()
.is_some_and(|bb| camera.aab_in_view(bb)),
mesh_in_view: chunk
.mesh_bounding_box()
.is_some_and(|bb| camera.aab_in_view(bb)),
instances_in_view: chunk
.block_instances_bounding_box()
.is_some_and(|bb| camera.aab_in_view(bb)),
};
(item.mesh_in_view || item.instances_in_view).then_some(item)
})
Expand Down
21 changes: 13 additions & 8 deletions all-is-cubes/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,15 +405,20 @@ impl Camera {

// Compute the view frustum's corner points,
// by unprojecting the corners of clip space.
let xy_limit = if self.options.debug_reduce_view_frustum {
0.5
} else {
1.
};
self.view_frustum = FrustumPoints {
lbn: self.project_ndc3_into_world(point3(-1., -1., 0.)),
rbn: self.project_ndc3_into_world(point3(1., -1., 0.)),
ltn: self.project_ndc3_into_world(point3(-1., 1., 0.)),
rtn: self.project_ndc3_into_world(point3(1., 1., 0.)),
lbf: self.project_ndc3_into_world(point3(-1., -1., 1.)),
rbf: self.project_ndc3_into_world(point3(1., -1., 1.)),
ltf: self.project_ndc3_into_world(point3(-1., 1., 1.)),
rtf: self.project_ndc3_into_world(point3(1., 1., 1.)),
lbn: self.project_ndc3_into_world(point3(-xy_limit, -xy_limit, 0.)),
rbn: self.project_ndc3_into_world(point3(xy_limit, -xy_limit, 0.)),
ltn: self.project_ndc3_into_world(point3(-xy_limit, xy_limit, 0.)),
rtn: self.project_ndc3_into_world(point3(xy_limit, xy_limit, 0.)),
lbf: self.project_ndc3_into_world(point3(-xy_limit, -xy_limit, 1.)),
rbf: self.project_ndc3_into_world(point3(xy_limit, -xy_limit, 1.)),
ltf: self.project_ndc3_into_world(point3(-xy_limit, xy_limit, 1.)),
rtf: self.project_ndc3_into_world(point3(xy_limit, xy_limit, 1.)),
bounds: Aab::ZERO,
};
self.view_frustum.compute_bounds();
Expand Down
25 changes: 13 additions & 12 deletions all-is-cubes/src/camera/graphics_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::math::{ps64, zo32, FreeCoordinate, PositiveSign, Rgb, Rgba, ZeroOne};
use crate::util::ShowStatus;

#[cfg(doc)]
use crate::{block::Block, space::Space};
use crate::{block::Block, camera::Camera, space::Space};

/// Options for controlling rendering (not affecting gameplay except informationally).
///
Expand Down Expand Up @@ -73,12 +73,6 @@ pub struct GraphicsOptions {
/// Whether to apply antialiasing techniques.
pub antialiasing: AntialiasingOption,

/// Whether to use frustum culling for drawing only in-view chunks and objects.
///
/// This option is for debugging and performance testing and should not have any
/// visible effects.
pub use_frustum_culling: bool,

/// Draw text overlay showing debug information.
pub debug_info_text: bool,

Expand All @@ -103,6 +97,13 @@ pub struct GraphicsOptions {

/// Draw the light rays that contribute to the selected block.
pub debug_light_rays_at_cursor: bool,

/// Causes [`Camera`] to compute a falsified view frustum which is 1/2 the width and height
/// it should be.
///
/// This may be used to visualize the effect of frustum culling that is performed via
/// [`Camera::aab_in_view()`].
pub debug_reduce_view_frustum: bool,
}

impl GraphicsOptions {
Expand Down Expand Up @@ -132,13 +133,13 @@ impl GraphicsOptions {
transparency: TransparencyOption::Volumetric,
show_ui: true,
antialiasing: AntialiasingOption::None,
use_frustum_culling: true,
debug_info_text: true,
debug_info_text_contents: ShowStatus::DEFAULT,
debug_behaviors: false,
debug_chunk_boxes: false,
debug_collision_boxes: false,
debug_light_rays_at_cursor: false,
debug_reduce_view_frustum: false,
};

/// Constrain fields to valid/practical values.
Expand All @@ -164,13 +165,13 @@ impl fmt::Debug for GraphicsOptions {
transparency,
show_ui,
antialiasing,
use_frustum_culling,
debug_info_text,
debug_info_text_contents,
debug_behaviors,
debug_chunk_boxes,
debug_collision_boxes,
debug_light_rays_at_cursor,
debug_reduce_view_frustum,
} = self;
// This custom impl reduces unnecessary text by stripping off NotNan wrappers.
f.debug_struct("GraphicsOptions")
Expand All @@ -185,13 +186,13 @@ impl fmt::Debug for GraphicsOptions {
.field("transparency", &transparency)
.field("show_ui", &show_ui)
.field("antialiasing", &antialiasing)
.field("use_frustum_culling", &use_frustum_culling)
.field("debug_info_text", &debug_info_text)
.field("debug_info_text_contents", &debug_info_text_contents)
.field("debug_behaviors", &debug_behaviors)
.field("debug_chunk_boxes", &debug_chunk_boxes)
.field("debug_collision_boxes", &debug_collision_boxes)
.field("debug_light_rays_at_cursor", &debug_light_rays_at_cursor)
.field("debug_reduce_view_frustum", &debug_reduce_view_frustum)
.finish()
}
}
Expand All @@ -215,13 +216,13 @@ impl Default for GraphicsOptions {
transparency: TransparencyOption::Volumetric,
show_ui: true,
antialiasing: AntialiasingOption::default(),
use_frustum_culling: true,
debug_info_text: true,
debug_info_text_contents: ShowStatus::DEFAULT,
debug_behaviors: false,
debug_chunk_boxes: false,
debug_collision_boxes: false,
debug_light_rays_at_cursor: false,
debug_reduce_view_frustum: false,
}
}
}
Expand Down Expand Up @@ -486,7 +487,6 @@ mod tests {
transparency: Volumetric,
show_ui: true,
antialiasing: None,
use_frustum_culling: true,
debug_info_text: true,
debug_info_text_contents: ShowStatus(
WORLD | STEP | RENDER | CURSOR,
Expand All @@ -495,6 +495,7 @@ mod tests {
debug_chunk_boxes: false,
debug_collision_boxes: false,
debug_light_rays_at_cursor: false,
debug_reduce_view_frustum: false,
}"
}
);
Expand Down

0 comments on commit a11611b

Please sign in to comment.