Skip to content

Commit

Permalink
Hack depth offset in order to make objects not disappear (#990)
Browse files Browse the repository at this point in the history
None of the things here is great, but it solves the problem at hand.
* smaller depth offset steps (experimented in tracking_hf & colmap with history on the image itself)
* bypass far z culling completely (far away layered images will "loose" more and more layers, but they won't disappear)
* limit image plane distance to not be too insane
* ensure use of f32 depth buffer for more consistency in this whole mess (precision was essentially unspecified so far)
  • Loading branch information
Wumpf committed Jan 30, 2023
1 parent 7f9d835 commit 9314faa
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
10 changes: 8 additions & 2 deletions crates/re_renderer/shader/utils/depth_offset.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
fn apply_depth_offset(position: Vec4, offset: f32) -> Vec4 {
// Z buffer z is computed using position.z/position.w,
// Therefore, to affect the final output by a given offset we need to multiply it with position.w.
// (This also means that we're loosing some precision!)
// This also means though that we're loosing a lot of precision
//
// We're using inverse z, i.e. 0.0 is far, 1.0 is near.
// We want a positive depth_offset_factor to move towards the viewer, so offset needs to be added.
//
// With this in place we still may cross over to 0.0 (the far plane) too early,
// making objects disappear into the far when they'd be otherwise stilil rendered.
// Since we're actually supposed to have an *infinite* far plane this should never happen!
// Therefore we simply dictacte a minimum z value.
// This ofc wrecks the depth offset and may cause z fighting with all very far away objects, but it's better than having things disappear!
return Vec4(
position.xy,
position.z + frame.depth_offset_factor * offset * position.w,
max(position.z + frame.depth_offset_factor * offset * position.w, f32eps),
position.w
);
}
12 changes: 6 additions & 6 deletions crates/re_renderer/src/view_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ impl ViewBuilder {

/// Depth format used for the main target of the view builder.
///
/// Consider using 32bit float depth buffer in the future if depth issues come up.
/// It is widely supported and has the best possible precision (with reverse infinite z projection which we're already using).
/// However, performance advice is still to use 24 bit depth buffering, see [Nvidia's Vulkan dos and dont's](https://developer.nvidia.com/blog/vulkan-dos-donts/):
/// > Don’t use 32-bit floating point depth formats, due to the performance cost, unless improved precision is actually required.
pub const MAIN_TARGET_DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24Plus;
/// [`wgpu::TextureFormat::Depth24Plus`] would be preferable for performance, see [Nvidia's Vulkan dos and dont's](https://developer.nvidia.com/blog/vulkan-dos-donts/).
/// However, the problem with being "24Plus" is that we no longer know what format we'll actually get, which is a problem e.g. for vertex shader determined depth offsets.
/// (This is a real concern - for example on Metal we always get a floating point target with this!)
/// [`wgpu::TextureFormat::Depth32Float`] on the other hand is widely supported and has the best possible precision (with reverse infinite z projection which we're already using).
pub const MAIN_TARGET_DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;

/// Enable MSAA always. This makes our pipeline less variable as well, as we need MSAA resolve steps if we want any MSAA at all!
///
Expand Down Expand Up @@ -385,7 +385,7 @@ impl ViewBuilder {

// See `depth_offset.wgsl`.
// Factor applied to depth offsets.
let depth_offset_factor = f32::EPSILON;
let depth_offset_factor = 1.0e-08; // Value determined by experimentation. Quite close to the f32 machine epsilon but a bit lower.

ctx.queue.write_buffer(
ctx.gpu_resources
Expand Down
2 changes: 1 addition & 1 deletion crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ fn obj_props_ui(
if ui
.add(
egui::DragValue::new(&mut distance)
.clamp_range(0.0..=f32::INFINITY)
.clamp_range(0.0..=1.0e8)
.speed(speed),
)
.on_hover_text("Controls how far away the image plane is.")
Expand Down

0 comments on commit 9314faa

Please sign in to comment.