Skip to content

Commit bf27c8e

Browse files
authored
Readback depth from GPU picking (#1752)
* gpu picking in the viewer picks up depth now * WebGL workarounds
1 parent d94ca3d commit bf27c8e

10 files changed

Lines changed: 422 additions & 91 deletions

File tree

crates/re_renderer/examples/picking.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,19 @@ impl framework::Example for Picking {
102102
PickingLayerProcessor::next_readback_result::<()>(re_ctx, READBACK_IDENTIFIER)
103103
{
104104
// Grab the middle pixel. usually we'd want to do something clever that snaps the the closest object of interest.
105-
let picked_pixel = picking_result.picking_data[(picking_result.rect.extent.x / 2
106-
+ (picking_result.rect.extent.y / 2) * picking_result.rect.extent.x)
107-
as usize];
105+
let picked_id = picking_result.picked_id(picking_result.rect.extent / 2);
106+
//let picked_position =
107+
// picking_result.picked_world_position(picking_result.rect.extent / 2);
108+
//dbg!(picked_position, picked_id);
108109

109110
self.mesh_is_hovered = false;
110-
if picked_pixel == MESH_ID {
111+
if picked_id == MESH_ID {
111112
self.mesh_is_hovered = true;
112-
} else if picked_pixel.object.0 != 0
113-
&& picked_pixel.object.0 <= self.point_sets.len() as u64
113+
} else if picked_id.object.0 != 0 && picked_id.object.0 <= self.point_sets.len() as u64
114114
{
115-
let point_set = &mut self.point_sets[picked_pixel.object.0 as usize - 1];
116-
point_set.radii[picked_pixel.instance.0 as usize] = Size::new_scene(0.1);
117-
point_set.colors[picked_pixel.instance.0 as usize] = Color32::DEBUG_COLOR;
115+
let point_set = &mut self.point_sets[picked_id.object.0 as usize - 1];
116+
point_set.radii[picked_id.instance.0 as usize] = Size::new_scene(0.1);
117+
point_set.colors[picked_id.instance.0 as usize] = Color32::DEBUG_COLOR;
118118
}
119119
}
120120

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Reads the content of a texture and writes it out as is.
2+
//
3+
// This is needed e.g. on WebGL to convert from a depth format to a regular color format that can be read back to the CPU.
4+
5+
#import <./types.wgsl>
6+
#import <./global_bindings.wgsl>
7+
#import <./screen_triangle_vertex.wgsl>
8+
9+
@group(1) @binding(0)
10+
var tex: texture_2d<f32>;
11+
12+
@fragment
13+
fn main(in: FragmentInput) -> @location(0) Vec4 {
14+
return textureSample(tex, nearest_sampler, in.texcoord);
15+
}

crates/re_renderer/src/allocator/gpu_readback_belt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ impl GpuReadbackBuffer {
8686
},
8787
);
8888

89-
self.range_in_chunk = start_offset..self.range_in_chunk.end;
89+
self.range_in_chunk =
90+
(start_offset + buffer_info.buffer_size_padded)..self.range_in_chunk.end;
9091
}
9192
}
9293

crates/re_renderer/src/config.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#[derive(Clone, Copy, Debug)]
66
pub enum HardwareTier {
77
/// For WebGL and native OpenGL. Maintains strict WebGL capability.
8-
Basic,
8+
Web,
99

1010
/// Run natively with Vulkan/Metal but don't demand anything that isn't widely available.
1111
Native,
@@ -17,7 +17,15 @@ impl HardwareTier {
1717
/// Whether the current hardware tier supports sampling from textures with a sample count higher than 1.
1818
pub fn support_sampling_msaa_texture(&self) -> bool {
1919
match self {
20-
HardwareTier::Basic => false,
20+
HardwareTier::Web => false,
21+
HardwareTier::Native => true,
22+
}
23+
}
24+
25+
/// Whether the current hardware tier supports sampling from textures with a sample count higher than 1.
26+
pub fn support_depth_readback(&self) -> bool {
27+
match self {
28+
HardwareTier::Web => false,
2129
HardwareTier::Native => true,
2230
}
2331
}
@@ -27,7 +35,7 @@ impl Default for HardwareTier {
2735
fn default() -> Self {
2836
// Use "Basic" tier for actual web but also if someone forces the GL backend!
2937
if supported_backends() == wgpu::Backends::GL {
30-
HardwareTier::Basic
38+
HardwareTier::Web
3139
} else {
3240
HardwareTier::Native
3341
}
@@ -63,7 +71,11 @@ impl HardwareTier {
6371
/// Downlevel features required by the given tier.
6472
pub fn required_downlevel_capabilities(self) -> wgpu::DownlevelCapabilities {
6573
wgpu::DownlevelCapabilities {
66-
flags: wgpu::DownlevelFlags::empty(),
74+
flags: match self {
75+
HardwareTier::Web => wgpu::DownlevelFlags::empty(),
76+
// Require fully WebGPU compliance for the native tier.
77+
HardwareTier::Native => wgpu::DownlevelFlags::all(),
78+
},
6779
limits: Default::default(), // unused so far both here and in wgpu
6880
shader_model: wgpu::ShaderModel::Sm4,
6981
}

0 commit comments

Comments
 (0)