Skip to content

Commit

Permalink
Fix Z fighting with improved depth offset math (#1661)
Browse files Browse the repository at this point in the history
* Fix Z fighting with improved depth offset math

* Add comment
  • Loading branch information
emilk authored Mar 21, 2023
1 parent cc46d14 commit 8f5faa9
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 20 deletions.
3 changes: 0 additions & 3 deletions crates/re_renderer/shader/global_bindings.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ struct FrameUniformBuffer {

// Size used for all line radii given with Size::AUTO.
auto_size_lines: f32,

/// Factor used to compute depth offsets, see `depth_offset.wgsl`.
depth_offset_factor: f32,
};
@group(0) @binding(0)
var<uniform> frame: FrameUniformBuffer;
Expand Down
35 changes: 24 additions & 11 deletions crates/re_renderer/shader/utils/depth_offset.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,34 @@
#import <../types.wgsl>

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 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.
// We want a positive offset 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.
// making objects disappear into the far when they'd be otherwise still 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,
max(position.z + frame.depth_offset_factor * offset * position.w, f32eps),
position.w
);

if true {
// This path assumes a `f32` depth buffer!

// 1.0 * eps _should_ be enough, but in practice it causes Z-fighting for unknown reasons.
// Maybe because of GPU interpolation of vertex coordinates?
let eps = 5.0 * f32eps;

return Vec4(
position.xy,
max(position.z * (1.0 + eps * offset), f32eps),
position.w
);
} else {
// Causes Z-collision at far distances
let eps = f32eps;
return Vec4(
position.xy,
max(position.z + eps * offset * position.w, f32eps),
position.w
);
}
}
2 changes: 1 addition & 1 deletion crates/re_renderer/src/global_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub(crate) struct FrameUniformBuffer {
pub auto_size_lines: f32,

/// Factor used to compute depth offsets, see `depth_offset.wgsl`.
pub depth_offset_factor: wgpu_buffer_types::F32RowPadded,
pub end_padding: wgpu_buffer_types::PaddingRow,
}

pub(crate) struct GlobalBindings {
Expand Down
6 changes: 1 addition & 5 deletions crates/re_renderer/src/view_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,6 @@ impl ViewBuilder {
config.auto_size_config.line_radius
};

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

// Setup frame uniform buffer
let frame_uniform_buffer = create_and_fill_uniform_buffer(
ctx,
Expand All @@ -426,7 +422,7 @@ impl ViewBuilder {
auto_size_points: auto_size_points.0,
auto_size_lines: auto_size_lines.0,

depth_offset_factor: depth_offset_factor.into(),
end_padding: Default::default(),
},
);

Expand Down

1 comment on commit 8f5faa9

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rust Benchmark

Benchmark suite Current: 8f5faa9 Previous: cc46d14 Ratio
datastore/insert/batch/rects/insert 611571 ns/iter (± 9415) 565317 ns/iter (± 2299) 1.08
datastore/latest_at/batch/rects/query 1881 ns/iter (± 6) 1886 ns/iter (± 4) 1.00
datastore/latest_at/missing_components/primary 292 ns/iter (± 0) 288 ns/iter (± 0) 1.01
datastore/latest_at/missing_components/secondaries 444 ns/iter (± 2) 438 ns/iter (± 2) 1.01
datastore/range/batch/rects/query 156402 ns/iter (± 653) 151188 ns/iter (± 1404) 1.03
mono_points_arrow/generate_message_bundles 52018822 ns/iter (± 843344) 50404754 ns/iter (± 1433085) 1.03
mono_points_arrow/generate_messages 141149486 ns/iter (± 1422668) 137726076 ns/iter (± 1286028) 1.02
mono_points_arrow/encode_log_msg 170055896 ns/iter (± 1126383) 168393670 ns/iter (± 666625) 1.01
mono_points_arrow/encode_total 363977625 ns/iter (± 2799016) 357976122 ns/iter (± 2044978) 1.02
mono_points_arrow/decode_log_msg 190968672 ns/iter (± 992698) 189293393 ns/iter (± 1467086) 1.01
mono_points_arrow/decode_message_bundles 78083482 ns/iter (± 1164348) 75280283 ns/iter (± 1223855) 1.04
mono_points_arrow/decode_total 262339281 ns/iter (± 1681345) 259669775 ns/iter (± 1946560) 1.01
batch_points_arrow/generate_message_bundles 329826 ns/iter (± 1508) 325904 ns/iter (± 2232) 1.01
batch_points_arrow/generate_messages 6505 ns/iter (± 35) 6488 ns/iter (± 62) 1.00
batch_points_arrow/encode_log_msg 414182 ns/iter (± 1715) 364610 ns/iter (± 2285) 1.14
batch_points_arrow/encode_total 751231 ns/iter (± 2861) 718576 ns/iter (± 39620) 1.05
batch_points_arrow/decode_log_msg 355473 ns/iter (± 1844) 350364 ns/iter (± 1881) 1.01
batch_points_arrow/decode_message_bundles 2078 ns/iter (± 12) 2094 ns/iter (± 12) 0.99
batch_points_arrow/decode_total 387702 ns/iter (± 1851) 355309 ns/iter (± 1015) 1.09
arrow_mono_points/insert 7180897831 ns/iter (± 30015588) 6887514065 ns/iter (± 26945980) 1.04
arrow_mono_points/query 1862983 ns/iter (± 12336) 1774289 ns/iter (± 16320) 1.05
arrow_batch_points/insert 2895608 ns/iter (± 16668) 2658134 ns/iter (± 13467) 1.09
arrow_batch_points/query 16157 ns/iter (± 56) 16178 ns/iter (± 70) 1.00
arrow_batch_vecs/insert 46839 ns/iter (± 241) 42586 ns/iter (± 249) 1.10
arrow_batch_vecs/query 406390 ns/iter (± 4723) 388304 ns/iter (± 3594) 1.05
tuid/Tuid::random 34 ns/iter (± 0) 34 ns/iter (± 0) 1

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.