From 4df37f15265249145f913fc601d7d54bb20ad2f2 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 16:09:03 +0100 Subject: [PATCH 01/29] Replace the backproject scale with the familiar "meter" --- crates/re_data_store/src/entity_properties.rs | 13 ++-- crates/re_log_types/src/data.rs | 4 ++ crates/re_viewer/src/ui/selection_panel.rs | 59 +++++++++++-------- .../view_spatial/scene/scene_part/images.rs | 8 ++- crates/re_viewer/src/ui/view_spatial/ui.rs | 24 ++++---- 5 files changed, 67 insertions(+), 41 deletions(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 5233f4ade951..7c2171f340df 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -66,8 +66,10 @@ pub struct EntityProperties { /// `None` means backprojection is disabled. pub backproject_pinhole_ent_path: Option, - /// Used to scale the resulting point cloud. - pub backproject_scale: EditableAutoValue, + /// How many depth units per world-space unit. e.g. 1000 for millimeters. + /// + /// This corresponds to [`Tensor::meter`]. + pub backproject_depth_meter: EditableAutoValue, /// Used to scale the radii of the points in the resulting point cloud. pub backproject_radius_scale: EditableAutoValue, @@ -94,7 +96,10 @@ impl EntityProperties { .backproject_pinhole_ent_path .clone() .or(child.backproject_pinhole_ent_path.clone()), - backproject_scale: self.backproject_scale.or(&child.backproject_scale).clone(), + backproject_depth_meter: self + .backproject_depth_meter + .or(&child.backproject_depth_meter) + .clone(), backproject_radius_scale: self .backproject_radius_scale .or(&child.backproject_radius_scale) @@ -114,7 +119,7 @@ impl Default for EntityProperties { pinhole_image_plane_distance: EditableAutoValue::default(), backproject_depth: false, backproject_pinhole_ent_path: None, - backproject_scale: EditableAutoValue::default(), + backproject_depth_meter: EditableAutoValue::default(), backproject_radius_scale: EditableAutoValue::default(), } } diff --git a/crates/re_log_types/src/data.rs b/crates/re_log_types/src/data.rs index 779adfff4cf6..60d164b2f8b9 100644 --- a/crates/re_log_types/src/data.rs +++ b/crates/re_log_types/src/data.rs @@ -94,6 +94,10 @@ impl TensorDataType { } } + pub fn is_integer(&self) -> bool { + !self.is_float() + } + pub fn is_float(&self) -> bool { match self { Self::U8 diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index dd081928a6ed..47b3b970889f 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -525,37 +525,50 @@ fn depth_props_ui( ); ui.end_row(); - ui.label("Backproject scale"); - let mut scale = *entity_props.backproject_scale.get(); - let speed = (scale * 0.05).at_least(0.01); - if ui + { + ui.label("Backproject meter"); + let mut meter = *entity_props.backproject_depth_meter.get(); + let speed = (meter * 0.05).at_least(0.01); + let response = ui .add( - egui::DragValue::new(&mut scale) + egui::DragValue::new(&mut meter) .clamp_range(0.0..=1.0e8) .speed(speed), ) - .on_hover_text("Scales the backprojected point cloud") - .changed() - { - entity_props.backproject_scale = EditableAutoValue::UserEdited(scale); + .on_hover_text("How many depth values correspond to one work-space unit. For instance, 1000 means millimeters. Double-click to reset."); + if response.double_clicked() { + // reset to auto - the exacy value will be restored somewhere else + entity_props.backproject_depth_meter = EditableAutoValue::Auto(meter); + response.surrender_focus(); + } else if response.changed() { + entity_props.backproject_depth_meter = EditableAutoValue::UserEdited(meter); + } + ui.end_row(); } - ui.end_row(); - ui.label("Backproject radius scale"); - let mut radius_scale = *entity_props.backproject_radius_scale.get(); - let speed = (radius_scale * 0.001).at_least(0.001); - if ui - .add( - egui::DragValue::new(&mut radius_scale) - .clamp_range(0.0..=1.0e8) - .speed(speed), - ) - .on_hover_text("Scales the radii of the points in the backprojected point cloud") - .changed() { - entity_props.backproject_radius_scale = EditableAutoValue::UserEdited(radius_scale); + ui.label("Backproject radius scale"); + let mut radius_scale = *entity_props.backproject_radius_scale.get(); + let speed = (radius_scale * 0.001).at_least(0.001); + let response = ui + .add( + egui::DragValue::new(&mut radius_scale) + .clamp_range(0.0..=1.0e8) + .speed(speed), + ) + .on_hover_text( + "Scales the radii of the points in the backprojected point cloud. Double-click to reset.", + ); + if response.double_clicked() { + // reset to auto - the exacy value will be restored somewhere else + entity_props.backproject_radius_scale = EditableAutoValue::Auto(radius_scale); + response.surrender_focus(); + } else if response.changed() { + entity_props.backproject_radius_scale = + EditableAutoValue::UserEdited(radius_scale); + } + ui.end_row(); } - ui.end_row(); // TODO(cmc): This should apply to the depth map entity as a whole, but for that we // need to get the current hardcoded colormapping out of the image cache first. diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 9f1ce70b2c6b..fc0721447f99 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -299,7 +299,13 @@ impl ImagesPart { } }; - let scale = *properties.backproject_scale.get(); + let meter = *properties.backproject_depth_meter.get(); + let scale = match data { + // the GPU normalizes the u16 to [0, 1] during texture smapler: + DepthCloudDepthData::U16(_) => u16::MAX as f32 / meter, + + DepthCloudDepthData::F32(_) => 1.0 / meter, + }; let radius_scale = *properties.backproject_radius_scale.get(); let (h, w) = (tensor.shape()[0].size, tensor.shape()[1].size); diff --git a/crates/re_viewer/src/ui/view_spatial/ui.rs b/crates/re_viewer/src/ui/view_spatial/ui.rs index 4cf7ac86cd9b..74f91d945aea 100644 --- a/crates/re_viewer/src/ui/view_spatial/ui.rs +++ b/crates/re_viewer/src/ui/view_spatial/ui.rs @@ -4,7 +4,7 @@ use re_format::format_f32; use egui::{NumExt, WidgetText}; use macaw::BoundingBox; -use re_log_types::component_types::{Tensor, TensorData, TensorDataMeaning}; +use re_log_types::component_types::{Tensor, TensorDataMeaning}; use re_renderer::renderer::OutlineConfig; use crate::{ @@ -228,18 +228,16 @@ impl ViewSpatialState { let tensor = tensor.as_ref().unwrap(); let mut properties = data_blueprint.data_blueprints_individual().get(entity_path); - if properties.backproject_scale.is_auto() { - let auto = tensor.meter.map_or_else( - || match &tensor.data { - TensorData::U16(_) => 1.0 / u16::MAX as f32, - _ => 1.0, - }, - |meter| match &tensor.data { - TensorData::U16(_) => 1.0 / meter * u16::MAX as f32, - _ => meter, - }, - ); - properties.backproject_scale = EditableAutoValue::Auto(auto); + if properties.backproject_depth_meter.is_auto() { + let auto = tensor.meter.unwrap_or_else(|| { + use re_log_types::component_types::TensorTrait as _; + if tensor.dtype().is_integer() { + 1000.0 + } else { + 1.0 + } + }); + properties.backproject_depth_meter = EditableAutoValue::Auto(auto); } if properties.backproject_radius_scale.is_auto() { From 61faf4355a5e153f9ed871ba552bfee10be8c831 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 16:09:21 +0100 Subject: [PATCH 02/29] Assume depth images usually start at zero --- crates/re_viewer/src/misc/caches/tensor_image_cache.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs index 7ecb0bb1b0d7..3e1970781825 100644 --- a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs +++ b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs @@ -461,6 +461,8 @@ fn depth_tensor_as_color_image(tensor: &Tensor) -> anyhow::Result { "Depth image had non-finite values" ); + min = min.min(0.0); // Depth ususally start at zero. + if min == max { // Uniform image. We can't remap it to a 0-1 range, so do whatever: min = 0.0; From e18a1c51b0269b22f78e6d72dd3fd3f941c97010 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 16:55:24 +0100 Subject: [PATCH 03/29] Make the depth point radius scale more sane --- crates/re_data_store/src/entity_properties.rs | 4 +++- crates/re_renderer/examples/depth_cloud.rs | 2 +- crates/re_renderer/shader/depth_cloud.wgsl | 7 ++++--- .../re_renderer/src/renderer/depth_cloud.rs | 11 +++++----- crates/re_viewer/src/ui/selection_panel.rs | 5 ++--- .../view_spatial/scene/scene_part/images.rs | 20 +++++++++++++------ crates/re_viewer/src/ui/view_spatial/ui.rs | 16 ++------------- 7 files changed, 32 insertions(+), 33 deletions(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 7c2171f340df..83e89f1bc564 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -72,6 +72,8 @@ pub struct EntityProperties { pub backproject_depth_meter: EditableAutoValue, /// Used to scale the radii of the points in the resulting point cloud. + /// + /// Default is 1.0. pub backproject_radius_scale: EditableAutoValue, } @@ -120,7 +122,7 @@ impl Default for EntityProperties { backproject_depth: false, backproject_pinhole_ent_path: None, backproject_depth_meter: EditableAutoValue::default(), - backproject_radius_scale: EditableAutoValue::default(), + backproject_radius_scale: EditableAutoValue::Auto(1.0), } } } diff --git a/crates/re_renderer/examples/depth_cloud.rs b/crates/re_renderer/examples/depth_cloud.rs index 67cf08528b7b..05d26d84ace2 100644 --- a/crates/re_renderer/examples/depth_cloud.rs +++ b/crates/re_renderer/examples/depth_cloud.rs @@ -175,7 +175,7 @@ impl RenderDepthClouds { &[DepthCloud { depth_camera_extrinsics: world_from_obj, depth_camera_intrinsics: *intrinsics, - radius_scale: *radius_scale, + point_radius_from_normalized_depth: *radius_scale, depth_dimensions: depth.dimensions, depth_data: depth.data.clone(), colormap: re_renderer::ColorMap::ColorMapTurbo, diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index 912dfe38d411..ae5e15873d6c 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -44,7 +44,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { var data: PointData; data.pos_in_world = pos_in_world.xyz; - data.unresolved_radius = norm_linear_depth * depth_cloud_info.radius_scale; + data.unresolved_radius = depth_cloud_info.point_radius_from_normalized_depth * norm_linear_depth; data.color = color; return data; @@ -61,8 +61,8 @@ struct DepthCloudInfo { /// Only supports pinhole cameras at the moment. depth_camera_intrinsics: Mat3, - /// The scale to apply to the radii of the backprojected points. - radius_scale: f32, + /// Point radius is calculated as normalized depth times this value. + point_radius_from_normalized_depth: f32, /// Configures color mapping mode, see `colormap.wgsl`. colormap: u32, @@ -70,6 +70,7 @@ struct DepthCloudInfo { /// Outline mask id for the outline mask pass. outline_mask_id: UVec2, }; + @group(1) @binding(0) var depth_cloud_info: DepthCloudInfo; diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 2bd76b61dc85..2072521f5b7e 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -44,7 +44,8 @@ mod gpu_data { pub depth_camera_extrinsics: crate::wgpu_buffer_types::Mat4, pub depth_camera_intrinsics: crate::wgpu_buffer_types::Mat3, - pub radius_scale: f32, + /// Point radius is calculated as depth times this value. + pub point_radius_from_normalized_depth: f32, pub colormap: u32, pub outline_mask_id: crate::wgpu_buffer_types::UVec2, @@ -84,8 +85,8 @@ pub struct DepthCloud { /// Only supports pinhole cameras at the moment. pub depth_camera_intrinsics: glam::Mat3, - /// The scale to apply to the radii of the backprojected points. - pub radius_scale: f32, + /// Point radius is calculated as depth times this value. + pub point_radius_from_normalized_depth: f32, /// The dimensions of the depth texture in pixels. pub depth_dimensions: glam::UVec2, @@ -107,7 +108,7 @@ impl Default for DepthCloud { Self { depth_camera_extrinsics: glam::Mat4::IDENTITY, depth_camera_intrinsics: glam::Mat3::IDENTITY, - radius_scale: 1.0, + point_radius_from_normalized_depth: 1e-3, depth_dimensions: glam::UVec2::ZERO, depth_data: DepthCloudDepthData::default(), colormap: ColorMap::ColorMapTurbo, @@ -162,7 +163,7 @@ impl DepthCloudDrawData { depth_clouds.iter().map(|info| gpu_data::DepthCloudInfoUBO { depth_camera_extrinsics: info.depth_camera_extrinsics.into(), depth_camera_intrinsics: info.depth_camera_intrinsics.into(), - radius_scale: info.radius_scale, + point_radius_from_normalized_depth: info.point_radius_from_normalized_depth, colormap: info.colormap as u32, outline_mask_id: info.outline_mask_id.0.unwrap_or_default().into(), end_padding: Default::default(), diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 47b3b970889f..5df819a1739b 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -549,7 +549,7 @@ fn depth_props_ui( { ui.label("Backproject radius scale"); let mut radius_scale = *entity_props.backproject_radius_scale.get(); - let speed = (radius_scale * 0.001).at_least(0.001); + let speed = (radius_scale * 0.01).at_least(0.001); let response = ui .add( egui::DragValue::new(&mut radius_scale) @@ -560,8 +560,7 @@ fn depth_props_ui( "Scales the radii of the points in the backprojected point cloud. Double-click to reset.", ); if response.double_clicked() { - // reset to auto - the exacy value will be restored somewhere else - entity_props.backproject_radius_scale = EditableAutoValue::Auto(radius_scale); + entity_props.backproject_radius_scale = EditableAutoValue::Auto(1.0); response.surrender_focus(); } else if response.changed() { entity_props.backproject_radius_scale = diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index fc0721447f99..b92051a4db3e 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -278,9 +278,10 @@ impl ImagesPart { }; // TODO(cmc): getting to those extrinsics is no easy task :| - let Some(extrinsics) = pinhole_ent_path - .parent() - .and_then(|ent_path| transforms.reference_from_entity(&ent_path)) else { + let extrinsics = pinhole_ent_path + .parent() + .and_then(|ent_path| transforms.reference_from_entity(&ent_path)); + let Some(extrinsics) = extrinsics else { re_log::warn_once!("Couldn't fetch pinhole extrinsics at {pinhole_ent_path:?}"); return; }; @@ -291,9 +292,9 @@ impl ImagesPart { TensorData::U16(data) => DepthCloudDepthData::U16(data.clone()), TensorData::F32(data) => DepthCloudDepthData::F32(data.clone()), _ => { - let discriminant = std::mem::discriminant(&tensor.data); re_log::warn_once!( - "Tensor datatype is not supported for backprojection ({discriminant:?})" + "Tensor datatype {} is not supported for backprojection", + tensor.dtype() ); return; } @@ -324,10 +325,17 @@ impl ImagesPart { }, }; + // By default, we assign a radius to each point so that each point becomes a ball + // that just barely touches its diagonally-neighboring pixel-point. + // This means the point radius increases with distance. + // It also increases with the field of view, and decreases with the resolution. + let point_radius_from_depth = 0.5_f32.sqrt() * intrinsics.fov_y().unwrap_or(1.0) / h as f32; + let point_radius_from_normalized_depth = radius_scale * point_radius_from_depth * scale; + scene.primitives.depth_clouds.push(DepthCloud { depth_camera_extrinsics: world_from_obj, depth_camera_intrinsics: intrinsics.image_from_cam.into(), - radius_scale, + point_radius_from_normalized_depth, depth_dimensions: dimensions, depth_data: data, colormap, diff --git a/crates/re_viewer/src/ui/view_spatial/ui.rs b/crates/re_viewer/src/ui/view_spatial/ui.rs index 74f91d945aea..d6c40f83bd2e 100644 --- a/crates/re_viewer/src/ui/view_spatial/ui.rs +++ b/crates/re_viewer/src/ui/view_spatial/ui.rs @@ -175,13 +175,7 @@ impl ViewSpatialState { &entity_path, scene_size, ); - Self::update_depth_cloud_property_heuristics( - ctx, - data_blueprint, - &query, - &entity_path, - scene_size, - ); + Self::update_depth_cloud_property_heuristics(ctx, data_blueprint, &query, &entity_path); } } @@ -221,7 +215,6 @@ impl ViewSpatialState { data_blueprint: &mut DataBlueprintTree, query: &re_arrow_store::LatestAtQuery, entity_path: &EntityPath, - scene_size: f32, ) { let tensor = query_latest_single::(&ctx.log_db.entity_db, entity_path, query); if tensor.as_ref().map(|t| t.meaning) == Some(TensorDataMeaning::Depth) { @@ -241,12 +234,7 @@ impl ViewSpatialState { } if properties.backproject_radius_scale.is_auto() { - let auto = if scene_size.is_finite() && scene_size > 0.0 { - f32::max(0.02, scene_size * 0.001) - } else { - 0.02 - }; - properties.backproject_radius_scale = EditableAutoValue::Auto(auto); + properties.backproject_radius_scale = EditableAutoValue::Auto(1.0); } data_blueprint From f783c0f1c74cd20c8592b1303741b69a7667daea Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 16:55:37 +0100 Subject: [PATCH 04/29] Fix an off-by-half error, giving all points an extra 0.5 pixels in radius --- crates/re_renderer/shader/utils/sphere_quad.wgsl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/re_renderer/shader/utils/sphere_quad.wgsl b/crates/re_renderer/shader/utils/sphere_quad.wgsl index 56df0e5aa134..6dfaddbc7f27 100644 --- a/crates/re_renderer/shader/utils/sphere_quad.wgsl +++ b/crates/re_renderer/shader/utils/sphere_quad.wgsl @@ -99,9 +99,13 @@ fn sphere_quad_coverage(world_position: Vec3, radius: f32, point_center: Vec3) - // https://www.shadertoy.com/view/MsSSWV // (but rearranged and labeled to it's easier to understand!) let d = ray_sphere_distance(ray, point_center, radius); - let smallest_distance_to_sphere = d.x; + let distance_to_sphere_surface = d.x; let closest_ray_dist = d.y; let pixel_world_size = approx_pixel_world_size_at(closest_ray_dist); - return 1.0 - saturate(smallest_distance_to_sphere / pixel_world_size); + let distance_to_surface_in_pixels = distance_to_sphere_surface / pixel_world_size; + + // At the surface we have 50% coverage, and it decreases with distance. + // Not that we have signed distances to the sphere surface. + return saturate(0.5 - distance_to_surface_in_pixels); } From 89faaf86c6d4099ca68c5b8850ee1655f070972a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 17:06:17 +0100 Subject: [PATCH 05/29] Add a fudge-factor --- .../re_viewer/src/ui/view_spatial/scene/scene_part/images.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index b92051a4db3e..730085fd38b8 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -307,7 +307,6 @@ impl ImagesPart { DepthCloudDepthData::F32(_) => 1.0 / meter, }; - let radius_scale = *properties.backproject_radius_scale.get(); let (h, w) = (tensor.shape()[0].size, tensor.shape()[1].size); let dimensions = glam::UVec2::new(w as _, h as _); @@ -329,9 +328,13 @@ impl ImagesPart { // that just barely touches its diagonally-neighboring pixel-point. // This means the point radius increases with distance. // It also increases with the field of view, and decreases with the resolution. + let radius_scale = *properties.backproject_radius_scale.get(); let point_radius_from_depth = 0.5_f32.sqrt() * intrinsics.fov_y().unwrap_or(1.0) / h as f32; let point_radius_from_normalized_depth = radius_scale * point_radius_from_depth * scale; + // TODO(emilk): we get gaps between diagonally adjacent points without this hack. WHY??? + let point_radius_from_normalized_depth = 1.1 * point_radius_from_normalized_depth; + scene.primitives.depth_clouds.push(DepthCloud { depth_camera_extrinsics: world_from_obj, depth_camera_intrinsics: intrinsics.image_from_cam.into(), From 8594073f9d347a6bf636840cd90fbba64bfb05a8 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 17:11:52 +0100 Subject: [PATCH 06/29] Improve tooltip --- crates/re_viewer/src/ui/selection_panel.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 5df819a1739b..9009b9652d78 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -535,7 +535,8 @@ fn depth_props_ui( .clamp_range(0.0..=1.0e8) .speed(speed), ) - .on_hover_text("How many depth values correspond to one work-space unit. For instance, 1000 means millimeters. Double-click to reset."); + .on_hover_text("How many depth values correspond to one work-space unit. For instance, 1000 means millimeters.\ + \nDouble-click to reset."); if response.double_clicked() { // reset to auto - the exacy value will be restored somewhere else entity_props.backproject_depth_meter = EditableAutoValue::Auto(meter); @@ -557,7 +558,9 @@ fn depth_props_ui( .speed(speed), ) .on_hover_text( - "Scales the radii of the points in the backprojected point cloud. Double-click to reset.", + "Scales the radii of the points in the backprojected point cloud.\n\ + With a scale of one, diagonally adjacent pixels at the same depth are sized so that they are just touching, leaving no gaps.\ + \nDouble-click to reset.", ); if response.double_clicked() { entity_props.backproject_radius_scale = EditableAutoValue::Auto(1.0); From 9034c5ce7cd001149a4890e222dff0f0071a9bf0 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 17:12:50 +0100 Subject: [PATCH 07/29] Fix typos --- crates/re_viewer/src/misc/caches/tensor_image_cache.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs index 3e1970781825..b346dc779d85 100644 --- a/crates/re_viewer/src/misc/caches/tensor_image_cache.rs +++ b/crates/re_viewer/src/misc/caches/tensor_image_cache.rs @@ -461,7 +461,7 @@ fn depth_tensor_as_color_image(tensor: &Tensor) -> anyhow::Result { "Depth image had non-finite values" ); - min = min.min(0.0); // Depth ususally start at zero. + min = min.min(0.0); // Depth usually start at zero. if min == max { // Uniform image. We can't remap it to a 0-1 range, so do whatever: From 5cb4e2d159b579e9002c423309b12aebba8acfec Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 17:15:52 +0100 Subject: [PATCH 08/29] Fix doclink --- crates/re_data_store/src/entity_properties.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 83e89f1bc564..4ad43256b0a2 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -68,7 +68,7 @@ pub struct EntityProperties { /// How many depth units per world-space unit. e.g. 1000 for millimeters. /// - /// This corresponds to [`Tensor::meter`]. + /// This corresponds to [`re_log_types::component_types::Tensor::meter`]. pub backproject_depth_meter: EditableAutoValue, /// Used to scale the radii of the points in the resulting point cloud. From 03173726081982741025c016bcfccc9fbcb26528 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 18:59:11 +0100 Subject: [PATCH 09/29] Fix the math --- .../src/ui/view_spatial/scene/scene_part/images.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 730085fd38b8..94fe0432a999 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -328,13 +328,11 @@ impl ImagesPart { // that just barely touches its diagonally-neighboring pixel-point. // This means the point radius increases with distance. // It also increases with the field of view, and decreases with the resolution. + let fov_y = intrinsics.fov_y().unwrap_or(1.0); + let point_radius_from_depth = 0.5_f32.sqrt() * (0.5 * fov_y).tan() / (0.5 * h as f32); let radius_scale = *properties.backproject_radius_scale.get(); - let point_radius_from_depth = 0.5_f32.sqrt() * intrinsics.fov_y().unwrap_or(1.0) / h as f32; let point_radius_from_normalized_depth = radius_scale * point_radius_from_depth * scale; - // TODO(emilk): we get gaps between diagonally adjacent points without this hack. WHY??? - let point_radius_from_normalized_depth = 1.1 * point_radius_from_normalized_depth; - scene.primitives.depth_clouds.push(DepthCloud { depth_camera_extrinsics: world_from_obj, depth_camera_intrinsics: intrinsics.image_from_cam.into(), From a7fbbfcbca666201cd41f84ee22a07f381b3eaa5 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 19:46:16 +0100 Subject: [PATCH 10/29] fix typo Co-authored-by: Andreas Reich --- crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 94fe0432a999..f929ff18d61c 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -302,7 +302,7 @@ impl ImagesPart { let meter = *properties.backproject_depth_meter.get(); let scale = match data { - // the GPU normalizes the u16 to [0, 1] during texture smapler: + // the GPU normalizes the u16 to [0, 1] during texture sampling: DepthCloudDepthData::U16(_) => u16::MAX as f32 / meter, DepthCloudDepthData::F32(_) => 1.0 / meter, From 3deb14ccf072bd9b42a8c23abcbd4730be2bfa92 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 19:47:03 +0100 Subject: [PATCH 11/29] #[inline] --- crates/re_log_types/src/data.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/re_log_types/src/data.rs b/crates/re_log_types/src/data.rs index 60d164b2f8b9..248c67f3acb7 100644 --- a/crates/re_log_types/src/data.rs +++ b/crates/re_log_types/src/data.rs @@ -94,10 +94,12 @@ impl TensorDataType { } } + #[inline] pub fn is_integer(&self) -> bool { !self.is_float() } + #[inline] pub fn is_float(&self) -> bool { match self { Self::U8 @@ -112,6 +114,7 @@ impl TensorDataType { } } + #[inline] pub fn max_value(&self) -> f64 { match self { Self::U8 => u8::MAX as _, From ed32db856af2f45468c12e52f234ad50700890a5 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 19:47:45 +0100 Subject: [PATCH 12/29] Another typo --- crates/re_renderer/shader/utils/sphere_quad.wgsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_renderer/shader/utils/sphere_quad.wgsl b/crates/re_renderer/shader/utils/sphere_quad.wgsl index 6dfaddbc7f27..8b5bf9f46526 100644 --- a/crates/re_renderer/shader/utils/sphere_quad.wgsl +++ b/crates/re_renderer/shader/utils/sphere_quad.wgsl @@ -106,6 +106,6 @@ fn sphere_quad_coverage(world_position: Vec3, radius: f32, point_center: Vec3) - let distance_to_surface_in_pixels = distance_to_sphere_surface / pixel_world_size; // At the surface we have 50% coverage, and it decreases with distance. - // Not that we have signed distances to the sphere surface. + // Note that we have signed distances to the sphere surface. return saturate(0.5 - distance_to_surface_in_pixels); } From 13d4844c77b4b947f969b32c8475b01650e0da72 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 19:48:12 +0100 Subject: [PATCH 13/29] typo Co-authored-by: Andreas Reich --- crates/re_viewer/src/ui/selection_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 9009b9652d78..31c805bf7a6e 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -538,7 +538,7 @@ fn depth_props_ui( .on_hover_text("How many depth values correspond to one work-space unit. For instance, 1000 means millimeters.\ \nDouble-click to reset."); if response.double_clicked() { - // reset to auto - the exacy value will be restored somewhere else + // reset to auto - the exact value will be restored somewhere else entity_props.backproject_depth_meter = EditableAutoValue::Auto(meter); response.surrender_focus(); } else if response.changed() { From 2b103f2db367b6761d3fbeea7eb4b607341a5e1c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Thu, 23 Mar 2023 19:51:08 +0100 Subject: [PATCH 14/29] Adjust the feathering margins --- crates/re_renderer/shader/utils/sphere_quad.wgsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/re_renderer/shader/utils/sphere_quad.wgsl b/crates/re_renderer/shader/utils/sphere_quad.wgsl index 8b5bf9f46526..763406552adf 100644 --- a/crates/re_renderer/shader/utils/sphere_quad.wgsl +++ b/crates/re_renderer/shader/utils/sphere_quad.wgsl @@ -27,9 +27,9 @@ fn sphere_quad_span_perspective( let camera_offset = radius_sq * distance_to_camera_inv; var modified_radius = point_radius * distance_to_camera_inv * sqrt(distance_to_camera_sq - radius_sq); - // We're computing a coverage mask in the fragment shader - make sure the quad doesn't cut off our antialiasing. + // Add half a pixel of margin for the feathering we do for antialiasing the spheres. // It's fairly subtle but if we don't do this our spheres look slightly squarish - modified_radius += frame.pixel_world_size_from_camera_distance * camera_distance; + modified_radius += 0.5 * frame.pixel_world_size_from_camera_distance * camera_distance; return point_pos + pos_in_quad * modified_radius + camera_offset * quad_normal; @@ -48,9 +48,9 @@ fn sphere_quad_span_orthographic(point_pos: Vec3, point_radius: f32, top_bottom: let quad_up = cross(quad_right, quad_normal); let pos_in_quad = top_bottom * quad_up + left_right * quad_right; - // We're computing a coverage mask in the fragment shader - make sure the quad doesn't cut off our antialiasing. + // Add half a pixel of margin for the feathering we do for antialiasing the spheres. // It's fairly subtle but if we don't do this our spheres look slightly squarish - let radius = point_radius + frame.pixel_world_size_from_camera_distance; + let radius = point_radius + 0.5 * frame.pixel_world_size_from_camera_distance; return point_pos + pos_in_quad * radius; } From f661a25b03127546d0aa1d75f3813abb33907b44 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 10:10:10 +0100 Subject: [PATCH 15/29] Clean up the depth texture uploading --- crates/re_renderer/shader/depth_cloud.wgsl | 1 + .../re_renderer/src/renderer/depth_cloud.rs | 83 +++++++++---------- 2 files changed, 41 insertions(+), 43 deletions(-) diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index ae5e15873d6c..42c772331885 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -52,6 +52,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { // --- +/// Keep in sync with `DepthCloudInfoUBO` in `depth_cloud.rs`. struct DepthCloudInfo { /// The extrinsincs of the camera used for the projection. extrinsincs: Mat4, diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 2072521f5b7e..7dffa4f3cbf1 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -42,11 +42,14 @@ mod gpu_data { #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] pub struct DepthCloudInfoUBO { pub depth_camera_extrinsics: crate::wgpu_buffer_types::Mat4, + pub depth_camera_intrinsics: crate::wgpu_buffer_types::Mat3, /// Point radius is calculated as depth times this value. pub point_radius_from_normalized_depth: f32, + pub colormap: u32, + pub outline_mask_id: crate::wgpu_buffer_types::UVec2, pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 8], @@ -58,6 +61,9 @@ mod gpu_data { /// This is either `u16` or `f32` values; in both cases the data will be uploaded to the shader /// as-is. /// For `u16`s, this results in a `Depth16Unorm` texture, otherwise an `R32Float`. +/// The reason we normalize `u16` is so that the shader can use a `float` texture in both cases. +/// However, it means we need to multiply the sampled value by `65535.0` in the shader to get +/// the actual depth. /// /// The shader assumes that this is normalized, linear, non-flipped depth using the camera /// position as reference point (not the camera plane!). @@ -103,20 +109,6 @@ pub struct DepthCloud { pub outline_mask_id: OutlineMaskPreference, } -impl Default for DepthCloud { - fn default() -> Self { - Self { - depth_camera_extrinsics: glam::Mat4::IDENTITY, - depth_camera_intrinsics: glam::Mat3::IDENTITY, - point_radius_from_normalized_depth: 1e-3, - depth_dimensions: glam::UVec2::ZERO, - depth_data: DepthCloudDepthData::default(), - colormap: ColorMap::ColorMapTurbo, - outline_mask_id: OutlineMaskPreference::NONE, - } - } -} - #[derive(Clone)] struct DepthCloudDrawInstance { bind_group: GpuBindGroup, @@ -173,28 +165,41 @@ impl DepthCloudDrawData { let mut instances = Vec::with_capacity(depth_clouds.len()); for (depth_cloud, ubo) in depth_clouds.iter().zip(depth_cloud_ubos.into_iter()) { let depth_texture = match &depth_cloud.depth_data { - // On native, we can use D16 textures without issues, but they aren't supported on - // the web (and won't ever be on the WebGL backend, see - // https://github.com/gfx-rs/wgpu/issues/3537). - // - // TODO(cmc): use an RG8 texture and unpack it manually in the shader instead. - #[cfg(not(target_arch = "wasm32"))] DepthCloudDepthData::U16(data) => { - create_and_upload_texture(ctx, depth_cloud, data.as_slice(), false) - } - #[cfg(target_arch = "wasm32")] - DepthCloudDepthData::U16(data) => { - use itertools::Itertools as _; - let dataf32 = data - .as_slice() - .iter() - .map(|d| *d as f32 / u16::MAX as f32) - .collect_vec(); - create_and_upload_texture(ctx, depth_cloud, dataf32.as_slice(), true) - } - DepthCloudDepthData::F32(data) => { - create_and_upload_texture(ctx, depth_cloud, data.as_slice(), false) + // On native, we can use D16 textures without issues, but they aren't supported on + // the web (and won't ever be on the WebGL backend, see + // https://github.com/gfx-rs/wgpu/issues/3537). + // + // TODO(cmc): use an RG8 texture and unpack it manually in the shader instead. + if cfg!(target_arch = "wasm32") { + // Manual normalization: + use itertools::Itertools as _; + let dataf32 = data + .as_slice() + .iter() + .map(|d| *d as f32 / u16::MAX as f32) + .collect_vec(); + create_and_upload_texture( + ctx, + depth_cloud, + dataf32.as_slice(), + wgpu::TextureFormat::R32Float, + ) + } else { + create_and_upload_texture( + ctx, + depth_cloud, + data.as_slice(), + wgpu::TextureFormat::Depth16Unorm, + ) + } } + DepthCloudDepthData::F32(data) => create_and_upload_texture( + ctx, + depth_cloud, + data.as_slice(), + wgpu::TextureFormat::R32Float, + ), }; instances.push(DepthCloudDrawInstance { @@ -223,7 +228,7 @@ fn create_and_upload_texture( ctx: &mut RenderContext, depth_cloud: &DepthCloud, data: &[T], - force_32bit: bool, + depth_format: wgpu::TextureFormat, ) -> GpuTexture { crate::profile_function!(); @@ -232,14 +237,6 @@ fn create_and_upload_texture( height: depth_cloud.depth_dimensions.y, depth_or_array_layers: 1, }; - let depth_format = if force_32bit { - wgpu::TextureFormat::R32Float - } else { - match depth_cloud.depth_data { - DepthCloudDepthData::U16(_) => wgpu::TextureFormat::Depth16Unorm, - DepthCloudDepthData::F32(_) => wgpu::TextureFormat::R32Float, - } - }; let depth_texture_desc = TextureDesc { label: "depth_texture".into(), size: depth_texture_size, From 5603fa0b38f5058971f3ca2061ecbc34e05b24fe Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 10:23:57 +0100 Subject: [PATCH 16/29] Better docs --- crates/re_renderer/src/renderer/depth_cloud.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 7dffa4f3cbf1..70e6c55cb6d5 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -166,13 +166,12 @@ impl DepthCloudDrawData { for (depth_cloud, ubo) in depth_clouds.iter().zip(depth_cloud_ubos.into_iter()) { let depth_texture = match &depth_cloud.depth_data { DepthCloudDepthData::U16(data) => { - // On native, we can use D16 textures without issues, but they aren't supported on - // the web (and won't ever be on the WebGL backend, see - // https://github.com/gfx-rs/wgpu/issues/3537). - // - // TODO(cmc): use an RG8 texture and unpack it manually in the shader instead. if cfg!(target_arch = "wasm32") { - // Manual normalization: + // Web: manual normalization because Depth16Unorm textures aren't supported on + // the web (and won't ever be on the WebGL backend, see + // https://github.com/gfx-rs/wgpu/issues/3537). + // + // TODO(cmc): use an RG8 texture and unpack it manually in the shader instead. use itertools::Itertools as _; let dataf32 = data .as_slice() @@ -186,6 +185,8 @@ impl DepthCloudDrawData { wgpu::TextureFormat::R32Float, ) } else { + // Native: We use Depth16Unorm over R16Unorm beacuse the latter is behind a feature flag, + // and not avilable on OpenGL backends. create_and_upload_texture( ctx, depth_cloud, From 37d8725eb70663dd746524b027183104d23028e6 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 10:34:28 +0100 Subject: [PATCH 17/29] fix typos --- crates/re_renderer/src/renderer/depth_cloud.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 70e6c55cb6d5..d80f7b288dbe 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -185,8 +185,8 @@ impl DepthCloudDrawData { wgpu::TextureFormat::R32Float, ) } else { - // Native: We use Depth16Unorm over R16Unorm beacuse the latter is behind a feature flag, - // and not avilable on OpenGL backends. + // Native: We use Depth16Unorm over R16Unorm because the latter is behind a feature flag, + // and not available on OpenGL backends. create_and_upload_texture( ctx, depth_cloud, From 4964a546f8caacbc1bfad4d26b2785e4b3b49e74 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 10:59:03 +0100 Subject: [PATCH 18/29] Use world depth values in the shader and simplify user code --- crates/re_renderer/examples/depth_cloud.rs | 15 ++--- crates/re_renderer/shader/depth_cloud.wgsl | 25 +++++--- .../re_renderer/src/renderer/depth_cloud.rs | 63 ++++++++++++++----- .../view_spatial/scene/scene_part/images.rs | 15 ++--- 4 files changed, 76 insertions(+), 42 deletions(-) diff --git a/crates/re_renderer/examples/depth_cloud.rs b/crates/re_renderer/examples/depth_cloud.rs index 05d26d84ace2..e51b7b1e4931 100644 --- a/crates/re_renderer/examples/depth_cloud.rs +++ b/crates/re_renderer/examples/depth_cloud.rs @@ -47,7 +47,7 @@ struct RenderDepthClouds { albedo_handle: GpuTexture2DHandle, scale: f32, - radius_scale: f32, + point_radius_from_world_depth: f32, intrinsics: glam::Mat3, camera_control: CameraControl, @@ -72,7 +72,7 @@ impl RenderDepthClouds { let Self { depth, scale, - radius_scale, + point_radius_from_world_depth, intrinsics, .. } = self; @@ -93,7 +93,7 @@ impl RenderDepthClouds { ( pos_in_world * *scale, Color32::from_gray((linear_depth * 255.0) as u8), - Size(linear_depth * *radius_scale), + Size(linear_depth * *point_radius_from_world_depth), ) }) .multiunzip(); @@ -163,7 +163,7 @@ impl RenderDepthClouds { let Self { depth, scale, - radius_scale, + point_radius_from_world_depth, intrinsics, .. } = self; @@ -175,7 +175,8 @@ impl RenderDepthClouds { &[DepthCloud { depth_camera_extrinsics: world_from_obj, depth_camera_intrinsics: *intrinsics, - point_radius_from_normalized_depth: *radius_scale, + world_depth_from_data_depth: 1.0, + point_radius_from_world_depth: *point_radius_from_world_depth, depth_dimensions: depth.dimensions, depth_data: depth.data.clone(), colormap: re_renderer::ColorMap::ColorMapTurbo, @@ -246,7 +247,7 @@ impl framework::Example for RenderDepthClouds { ); let scale = 50.0; - let radius_scale = 0.1; + let point_radius_from_world_depth = 0.1; // hardcoded intrinsics for nyud dataset let focal_length = depth.dimensions.x as f32 * 0.7; @@ -264,7 +265,7 @@ impl framework::Example for RenderDepthClouds { albedo_handle, scale, - radius_scale, + point_radius_from_world_depth, intrinsics, camera_control: CameraControl::RotateAroundCenter, diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index 42c772331885..dd8f682a716a 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -25,10 +25,12 @@ fn compute_point_data(quad_idx: i32) -> PointData { let texcoords = IVec2(quad_idx % wh.x, quad_idx / wh.x); // TODO(cmc): expose knobs to linearize/normalize/flip/cam-to-plane depth. - let norm_linear_depth = textureLoad(depth_texture, texcoords, 0).x; + let world_space_depth = depth_cloud_info.world_depth_from_texture_value * textureLoad(depth_texture, texcoords, 0).x; + + let max_depth = 10.0; // TODO: get from uniform buffer // TODO(cmc): albedo textures - let color = Vec4(colormap_srgb(depth_cloud_info.colormap, norm_linear_depth), 1.0); + let color = Vec4(colormap_srgb(depth_cloud_info.colormap, world_space_depth / max_depth), 1.0); // TODO(cmc): This assumes a pinhole camera; need to support other kinds at some point. let intrinsics = depth_cloud_info.depth_camera_intrinsics; @@ -36,15 +38,15 @@ fn compute_point_data(quad_idx: i32) -> PointData { let offset = Vec2(intrinsics[2][0], intrinsics[2][1]); let pos_in_obj = Vec3( - (Vec2(texcoords) - offset) * norm_linear_depth / focal_length, - norm_linear_depth, + (Vec2(texcoords) - offset) * world_space_depth / focal_length, + world_space_depth, ); let pos_in_world = depth_cloud_info.extrinsincs * Vec4(pos_in_obj, 1.0); var data: PointData; data.pos_in_world = pos_in_world.xyz; - data.unresolved_radius = depth_cloud_info.point_radius_from_normalized_depth * norm_linear_depth; + data.unresolved_radius = depth_cloud_info.point_radius_from_world_depth * world_space_depth; data.color = color; return data; @@ -62,14 +64,17 @@ struct DepthCloudInfo { /// Only supports pinhole cameras at the moment. depth_camera_intrinsics: Mat3, - /// Point radius is calculated as normalized depth times this value. - point_radius_from_normalized_depth: f32, + /// Outline mask id for the outline mask pass. + outline_mask_id: UVec2, + + /// Multiplier to get world-space depth from whatever is in the texture. + world_depth_from_texture_value: f32, + + /// Point radius is calculated as world-space depth times this value. + point_radius_from_world_depth: f32, /// Configures color mapping mode, see `colormap.wgsl`. colormap: u32, - - /// Outline mask id for the outline mask pass. - outline_mask_id: UVec2, }; @group(1) @binding(0) diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index d80f7b288dbe..51b3d2833bda 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -45,14 +45,51 @@ mod gpu_data { pub depth_camera_intrinsics: crate::wgpu_buffer_types::Mat3, - /// Point radius is calculated as depth times this value. - pub point_radius_from_normalized_depth: f32, + pub outline_mask_id: crate::wgpu_buffer_types::UVec2, + + /// Multiplier to get world-space depth from whatever is in the texture. + pub world_depth_from_texture_value: f32, + + /// Point radius is calculated as world-space depth times this value. + pub point_radius_from_world_depth: f32, pub colormap: u32, + pub row_pad: [u32; 3], - pub outline_mask_id: crate::wgpu_buffer_types::UVec2, + pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 4 - 3 - 1 - 1], + } - pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 8], + impl DepthCloudInfoUBO { + pub fn from_depth_cloud(depth_cloud: &super::DepthCloud) -> Self { + let super::DepthCloud { + depth_camera_extrinsics, + depth_camera_intrinsics, + world_depth_from_data_depth, + point_radius_from_world_depth, + depth_dimensions: _, + depth_data, + colormap, + outline_mask_id, + } = depth_cloud; + + let user_depth_from_texture_value = match depth_data { + super::DepthCloudDepthData::U16(_) => 65535.0, // un-normalize + super::DepthCloudDepthData::F32(_) => 1.0, + }; + let world_depth_from_texture_value = + world_depth_from_data_depth * user_depth_from_texture_value; + + Self { + depth_camera_extrinsics: (*depth_camera_extrinsics).into(), + depth_camera_intrinsics: (*depth_camera_intrinsics).into(), + outline_mask_id: outline_mask_id.0.unwrap_or_default().into(), + world_depth_from_texture_value, + point_radius_from_world_depth: *point_radius_from_world_depth, + colormap: *colormap as u32, + row_pad: Default::default(), + end_padding: Default::default(), + } + } } } @@ -91,8 +128,11 @@ pub struct DepthCloud { /// Only supports pinhole cameras at the moment. pub depth_camera_intrinsics: glam::Mat3, - /// Point radius is calculated as depth times this value. - pub point_radius_from_normalized_depth: f32, + /// Multiplier to get world-space depth from whatever is in [`depth_data`]. + pub world_depth_from_data_depth: f32, + + /// Point radius is calculated as world-space depth times this value. + pub point_radius_from_world_depth: f32, /// The dimensions of the depth texture in pixels. pub depth_dimensions: glam::UVec2, @@ -152,14 +192,9 @@ impl DepthCloudDrawData { let depth_cloud_ubos = create_and_fill_uniform_buffer_batch( ctx, "depth_cloud_ubos".into(), - depth_clouds.iter().map(|info| gpu_data::DepthCloudInfoUBO { - depth_camera_extrinsics: info.depth_camera_extrinsics.into(), - depth_camera_intrinsics: info.depth_camera_intrinsics.into(), - point_radius_from_normalized_depth: info.point_radius_from_normalized_depth, - colormap: info.colormap as u32, - outline_mask_id: info.outline_mask_id.0.unwrap_or_default().into(), - end_padding: Default::default(), - }), + depth_clouds + .iter() + .map(gpu_data::DepthCloudInfoUBO::from_depth_cloud), ); let mut instances = Vec::with_capacity(depth_clouds.len()); diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index f929ff18d61c..f340b68c29c2 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -301,18 +301,10 @@ impl ImagesPart { }; let meter = *properties.backproject_depth_meter.get(); - let scale = match data { - // the GPU normalizes the u16 to [0, 1] during texture sampling: - DepthCloudDepthData::U16(_) => u16::MAX as f32 / meter, - - DepthCloudDepthData::F32(_) => 1.0 / meter, - }; let (h, w) = (tensor.shape()[0].size, tensor.shape()[1].size); let dimensions = glam::UVec2::new(w as _, h as _); - let world_from_obj = extrinsics * glam::Mat4::from_scale(glam::Vec3::splat(scale)); - let colormap = match *properties.color_mapper.get() { re_data_store::ColorMapper::ColorMap(colormap) => match colormap { re_data_store::ColorMap::Grayscale => ColorMap::Grayscale, @@ -331,12 +323,13 @@ impl ImagesPart { let fov_y = intrinsics.fov_y().unwrap_or(1.0); let point_radius_from_depth = 0.5_f32.sqrt() * (0.5 * fov_y).tan() / (0.5 * h as f32); let radius_scale = *properties.backproject_radius_scale.get(); - let point_radius_from_normalized_depth = radius_scale * point_radius_from_depth * scale; + let point_radius_from_world_depth = radius_scale * point_radius_from_depth; scene.primitives.depth_clouds.push(DepthCloud { - depth_camera_extrinsics: world_from_obj, + depth_camera_extrinsics: extrinsics, depth_camera_intrinsics: intrinsics.image_from_cam.into(), - point_radius_from_normalized_depth, + world_depth_from_data_depth: 1.0 / meter, + point_radius_from_world_depth, depth_dimensions: dimensions, depth_data: data, colormap, From 0e72422da1a855e2a224a9c8630372976cea2540 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 11:11:49 +0100 Subject: [PATCH 19/29] Better naming --- crates/re_data_store/src/entity_properties.rs | 10 +- crates/re_renderer/examples/depth_cloud.rs | 2 +- crates/re_renderer/shader/depth_cloud.wgsl | 4 +- .../re_renderer/src/renderer/depth_cloud.rs | 9 +- crates/re_viewer/src/ui/selection_panel.rs | 93 ++++++++++--------- .../view_spatial/scene/scene_part/images.rs | 10 +- crates/re_viewer/src/ui/view_spatial/ui.rs | 4 +- 7 files changed, 68 insertions(+), 64 deletions(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 4ad43256b0a2..4757f4ec4a44 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -69,7 +69,7 @@ pub struct EntityProperties { /// How many depth units per world-space unit. e.g. 1000 for millimeters. /// /// This corresponds to [`re_log_types::component_types::Tensor::meter`]. - pub backproject_depth_meter: EditableAutoValue, + pub depth_from_world_scale: EditableAutoValue, /// Used to scale the radii of the points in the resulting point cloud. /// @@ -98,9 +98,9 @@ impl EntityProperties { .backproject_pinhole_ent_path .clone() .or(child.backproject_pinhole_ent_path.clone()), - backproject_depth_meter: self - .backproject_depth_meter - .or(&child.backproject_depth_meter) + depth_from_world_scale: self + .depth_from_world_scale + .or(&child.depth_from_world_scale) .clone(), backproject_radius_scale: self .backproject_radius_scale @@ -121,7 +121,7 @@ impl Default for EntityProperties { pinhole_image_plane_distance: EditableAutoValue::default(), backproject_depth: false, backproject_pinhole_ent_path: None, - backproject_depth_meter: EditableAutoValue::default(), + depth_from_world_scale: EditableAutoValue::default(), backproject_radius_scale: EditableAutoValue::Auto(1.0), } } diff --git a/crates/re_renderer/examples/depth_cloud.rs b/crates/re_renderer/examples/depth_cloud.rs index e51b7b1e4931..4a54b0e34f64 100644 --- a/crates/re_renderer/examples/depth_cloud.rs +++ b/crates/re_renderer/examples/depth_cloud.rs @@ -173,7 +173,7 @@ impl RenderDepthClouds { let depth_cloud_draw_data = DepthCloudDrawData::new( re_ctx, &[DepthCloud { - depth_camera_extrinsics: world_from_obj, + world_from_obj, depth_camera_intrinsics: *intrinsics, world_depth_from_data_depth: 1.0, point_radius_from_world_depth: *point_radius_from_world_depth, diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index dd8f682a716a..424019b4c49a 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -42,7 +42,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { world_space_depth, ); - let pos_in_world = depth_cloud_info.extrinsincs * Vec4(pos_in_obj, 1.0); + let pos_in_world = depth_cloud_info.world_from_obj * Vec4(pos_in_obj, 1.0); var data: PointData; data.pos_in_world = pos_in_world.xyz; @@ -57,7 +57,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { /// Keep in sync with `DepthCloudInfoUBO` in `depth_cloud.rs`. struct DepthCloudInfo { /// The extrinsincs of the camera used for the projection. - extrinsincs: Mat4, + world_from_obj: Mat4, /// The intrinsics of the camera used for the projection. /// diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 51b3d2833bda..9ee7df98c0a2 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -41,7 +41,8 @@ mod gpu_data { #[repr(C, align(256))] #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] pub struct DepthCloudInfoUBO { - pub depth_camera_extrinsics: crate::wgpu_buffer_types::Mat4, + /// The extrinsics of the camera used for the projection. + pub world_from_obj: crate::wgpu_buffer_types::Mat4, pub depth_camera_intrinsics: crate::wgpu_buffer_types::Mat3, @@ -62,7 +63,7 @@ mod gpu_data { impl DepthCloudInfoUBO { pub fn from_depth_cloud(depth_cloud: &super::DepthCloud) -> Self { let super::DepthCloud { - depth_camera_extrinsics, + world_from_obj, depth_camera_intrinsics, world_depth_from_data_depth, point_radius_from_world_depth, @@ -80,7 +81,7 @@ mod gpu_data { world_depth_from_data_depth * user_depth_from_texture_value; Self { - depth_camera_extrinsics: (*depth_camera_extrinsics).into(), + world_from_obj: (*world_from_obj).into(), depth_camera_intrinsics: (*depth_camera_intrinsics).into(), outline_mask_id: outline_mask_id.0.unwrap_or_default().into(), world_depth_from_texture_value, @@ -121,7 +122,7 @@ impl Default for DepthCloudDepthData { pub struct DepthCloud { /// The extrinsics of the camera used for the projection. - pub depth_camera_extrinsics: glam::Mat4, + pub world_from_obj: glam::Mat4, /// The intrinsics of the camera used for the projection. /// diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 31c805bf7a6e..ce637295cf5d 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -525,52 +525,9 @@ fn depth_props_ui( ); ui.end_row(); - { - ui.label("Backproject meter"); - let mut meter = *entity_props.backproject_depth_meter.get(); - let speed = (meter * 0.05).at_least(0.01); - let response = ui - .add( - egui::DragValue::new(&mut meter) - .clamp_range(0.0..=1.0e8) - .speed(speed), - ) - .on_hover_text("How many depth values correspond to one work-space unit. For instance, 1000 means millimeters.\ - \nDouble-click to reset."); - if response.double_clicked() { - // reset to auto - the exact value will be restored somewhere else - entity_props.backproject_depth_meter = EditableAutoValue::Auto(meter); - response.surrender_focus(); - } else if response.changed() { - entity_props.backproject_depth_meter = EditableAutoValue::UserEdited(meter); - } - ui.end_row(); - } + depth_from_world_scale_ui(ui, &mut entity_props.depth_from_world_scale); - { - ui.label("Backproject radius scale"); - let mut radius_scale = *entity_props.backproject_radius_scale.get(); - let speed = (radius_scale * 0.01).at_least(0.001); - let response = ui - .add( - egui::DragValue::new(&mut radius_scale) - .clamp_range(0.0..=1.0e8) - .speed(speed), - ) - .on_hover_text( - "Scales the radii of the points in the backprojected point cloud.\n\ - With a scale of one, diagonally adjacent pixels at the same depth are sized so that they are just touching, leaving no gaps.\ - \nDouble-click to reset.", - ); - if response.double_clicked() { - entity_props.backproject_radius_scale = EditableAutoValue::Auto(1.0); - response.surrender_focus(); - } else if response.changed() { - entity_props.backproject_radius_scale = - EditableAutoValue::UserEdited(radius_scale); - } - ui.end_row(); - } + backproject_radius_scale_ui(ui, &mut entity_props.backproject_radius_scale); // TODO(cmc): This should apply to the depth map entity as a whole, but for that we // need to get the current hardcoded colormapping out of the image cache first. @@ -580,3 +537,49 @@ fn depth_props_ui( } } } + +fn depth_from_world_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoValue) { + ui.label("Backproject meter"); + let mut value = *property.get(); + let speed = (value * 0.05).at_least(0.01); + let response = ui + .add( + egui::DragValue::new(&mut value) + .clamp_range(0.0..=1.0e8) + .speed(speed), + ) + .on_hover_text("How many steps in the depth image correspond to one world-space unit. For instance, 1000 means millimeters.\ + \nDouble-click to reset."); + if response.double_clicked() { + // reset to auto - the exact value will be restored somewhere else + *property = EditableAutoValue::Auto(value); + response.surrender_focus(); + } else if response.changed() { + *property = EditableAutoValue::UserEdited(value); + } + ui.end_row(); +} + +fn backproject_radius_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoValue) { + ui.label("Backproject radius scale"); + let mut value = *property.get(); + let speed = (value * 0.01).at_least(0.001); + let response = ui + .add( + egui::DragValue::new(&mut value) + .clamp_range(0.0..=1.0e8) + .speed(speed), + ) + .on_hover_text( + "Scales the radii of the points in the backprojected point cloud.\n\ + With a scale of one, diagonally adjacent pixels at the same depth are sized so that they are just touching, leaving no gaps.\ + \nDouble-click to reset.", + ); + if response.double_clicked() { + *property = EditableAutoValue::Auto(1.0); + response.surrender_focus(); + } else if response.changed() { + *property = EditableAutoValue::UserEdited(value); + } + ui.end_row(); +} diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index f340b68c29c2..fab6c17bbb48 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -278,10 +278,10 @@ impl ImagesPart { }; // TODO(cmc): getting to those extrinsics is no easy task :| - let extrinsics = pinhole_ent_path + let world_from_obj = pinhole_ent_path .parent() .and_then(|ent_path| transforms.reference_from_entity(&ent_path)); - let Some(extrinsics) = extrinsics else { + let Some(world_from_obj) = world_from_obj else { re_log::warn_once!("Couldn't fetch pinhole extrinsics at {pinhole_ent_path:?}"); return; }; @@ -300,7 +300,7 @@ impl ImagesPart { } }; - let meter = *properties.backproject_depth_meter.get(); + let depth_from_world_scale = *properties.depth_from_world_scale.get(); let (h, w) = (tensor.shape()[0].size, tensor.shape()[1].size); let dimensions = glam::UVec2::new(w as _, h as _); @@ -326,9 +326,9 @@ impl ImagesPart { let point_radius_from_world_depth = radius_scale * point_radius_from_depth; scene.primitives.depth_clouds.push(DepthCloud { - depth_camera_extrinsics: extrinsics, + world_from_obj, depth_camera_intrinsics: intrinsics.image_from_cam.into(), - world_depth_from_data_depth: 1.0 / meter, + world_depth_from_data_depth: 1.0 / depth_from_world_scale, point_radius_from_world_depth, depth_dimensions: dimensions, depth_data: data, diff --git a/crates/re_viewer/src/ui/view_spatial/ui.rs b/crates/re_viewer/src/ui/view_spatial/ui.rs index d6c40f83bd2e..abce7a87c64a 100644 --- a/crates/re_viewer/src/ui/view_spatial/ui.rs +++ b/crates/re_viewer/src/ui/view_spatial/ui.rs @@ -221,7 +221,7 @@ impl ViewSpatialState { let tensor = tensor.as_ref().unwrap(); let mut properties = data_blueprint.data_blueprints_individual().get(entity_path); - if properties.backproject_depth_meter.is_auto() { + if properties.depth_from_world_scale.is_auto() { let auto = tensor.meter.unwrap_or_else(|| { use re_log_types::component_types::TensorTrait as _; if tensor.dtype().is_integer() { @@ -230,7 +230,7 @@ impl ViewSpatialState { 1.0 } }); - properties.backproject_depth_meter = EditableAutoValue::Auto(auto); + properties.depth_from_world_scale = EditableAutoValue::Auto(auto); } if properties.backproject_radius_scale.is_auto() { From d5ee3c1fc7741a381ca16a576a6f9cab4685ad18 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 11:27:36 +0100 Subject: [PATCH 20/29] Fix bug in the image-hover code --- crates/re_viewer/src/ui/data_ui/image.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/re_viewer/src/ui/data_ui/image.rs b/crates/re_viewer/src/ui/data_ui/image.rs index 1bf208d51bba..bb3d5a483548 100644 --- a/crates/re_viewer/src/ui/data_ui/image.rs +++ b/crates/re_viewer/src/ui/data_ui/image.rs @@ -390,16 +390,16 @@ pub fn show_zoomed_image_region( let tensor = tensor_view.tensor; let text = match tensor.num_dim() { - 2 => tensor.get(&[x, y]).map(|v| format!("Val: {v}")), + 2 => tensor.get(&[y, x]).map(|v| format!("Val: {v}")), 3 => match tensor.shape()[2].size { 0 => Some("Cannot preview 0-size channel".to_owned()), - 1 => tensor.get(&[x, y, 0]).map(|v| format!("Val: {v}")), + 1 => tensor.get(&[y, x, 0]).map(|v| format!("Val: {v}")), 3 => { // TODO(jleibs): Track RGB ordering somehow -- don't just assume it if let (Some(r), Some(g), Some(b)) = ( - tensor_view.tensor.get(&[x, y, 0]), - tensor_view.tensor.get(&[x, y, 1]), - tensor_view.tensor.get(&[x, y, 2]), + tensor_view.tensor.get(&[y, x, 0]), + tensor_view.tensor.get(&[y, x, 1]), + tensor_view.tensor.get(&[y, x, 2]), ) { match (r, g, b) { ( @@ -420,10 +420,10 @@ pub fn show_zoomed_image_region( 4 => { // TODO(jleibs): Track RGB ordering somehow -- don't just assume it if let (Some(r), Some(g), Some(b), Some(a)) = ( - tensor_view.tensor.get(&[x, y, 0]), - tensor_view.tensor.get(&[x, y, 1]), - tensor_view.tensor.get(&[x, y, 2]), - tensor_view.tensor.get(&[x, y, 3]), + tensor_view.tensor.get(&[y, x, 0]), + tensor_view.tensor.get(&[y, x, 1]), + tensor_view.tensor.get(&[y, x, 2]), + tensor_view.tensor.get(&[y, x, 3]), ) { match (r, g, b, a) { ( From 51a21acc7bdbea0d1ee23cd90474466a54ce243e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 11:30:26 +0100 Subject: [PATCH 21/29] Use same depth range for the color map in the depth projection shader --- crates/re_renderer/examples/depth_cloud.rs | 1 + crates/re_renderer/shader/depth_cloud.wgsl | 7 ++++--- crates/re_renderer/src/renderer/depth_cloud.rs | 10 +++++++++- .../ui/view_spatial/scene/scene_part/images.rs | 16 +++++++++++++++- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/crates/re_renderer/examples/depth_cloud.rs b/crates/re_renderer/examples/depth_cloud.rs index 4a54b0e34f64..b40e93b35ab7 100644 --- a/crates/re_renderer/examples/depth_cloud.rs +++ b/crates/re_renderer/examples/depth_cloud.rs @@ -177,6 +177,7 @@ impl RenderDepthClouds { depth_camera_intrinsics: *intrinsics, world_depth_from_data_depth: 1.0, point_radius_from_world_depth: *point_radius_from_world_depth, + max_depth: 5.0, depth_dimensions: depth.dimensions, depth_data: depth.data.clone(), colormap: re_renderer::ColorMap::ColorMapTurbo, diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index 424019b4c49a..8c508a3e988d 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -27,10 +27,8 @@ fn compute_point_data(quad_idx: i32) -> PointData { // TODO(cmc): expose knobs to linearize/normalize/flip/cam-to-plane depth. let world_space_depth = depth_cloud_info.world_depth_from_texture_value * textureLoad(depth_texture, texcoords, 0).x; - let max_depth = 10.0; // TODO: get from uniform buffer - // TODO(cmc): albedo textures - let color = Vec4(colormap_srgb(depth_cloud_info.colormap, world_space_depth / max_depth), 1.0); + let color = Vec4(colormap_srgb(depth_cloud_info.colormap, world_space_depth / depth_cloud_info.max_depth), 1.0); // TODO(cmc): This assumes a pinhole camera; need to support other kinds at some point. let intrinsics = depth_cloud_info.depth_camera_intrinsics; @@ -73,6 +71,9 @@ struct DepthCloudInfo { /// Point radius is calculated as world-space depth times this value. point_radius_from_world_depth: f32, + /// The maximum depth value, for use with the colormap. + max_depth: f32, + /// Configures color mapping mode, see `colormap.wgsl`. colormap: u32, }; diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 9ee7df98c0a2..58de62d3383b 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -54,8 +54,11 @@ mod gpu_data { /// Point radius is calculated as world-space depth times this value. pub point_radius_from_world_depth: f32, + /// The maximum depth value, for use with the colormap. + pub max_depth: f32, + pub colormap: u32, - pub row_pad: [u32; 3], + pub row_pad: [u32; 2], pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 4 - 3 - 1 - 1], } @@ -67,6 +70,7 @@ mod gpu_data { depth_camera_intrinsics, world_depth_from_data_depth, point_radius_from_world_depth, + max_depth, depth_dimensions: _, depth_data, colormap, @@ -86,6 +90,7 @@ mod gpu_data { outline_mask_id: outline_mask_id.0.unwrap_or_default().into(), world_depth_from_texture_value, point_radius_from_world_depth: *point_radius_from_world_depth, + max_depth: *max_depth, colormap: *colormap as u32, row_pad: Default::default(), end_padding: Default::default(), @@ -135,6 +140,9 @@ pub struct DepthCloud { /// Point radius is calculated as world-space depth times this value. pub point_radius_from_world_depth: f32, + /// The maximum depth value, for use with the colormap. + pub max_depth: f32, + /// The dimensions of the depth texture in pixels. pub depth_dimensions: glam::UVec2, diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index fab6c17bbb48..997b52751920 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -301,6 +301,7 @@ impl ImagesPart { }; let depth_from_world_scale = *properties.depth_from_world_scale.get(); + let world_depth_from_data_depth = 1.0 / depth_from_world_scale; let (h, w) = (tensor.shape()[0].size, tensor.shape()[1].size); let dimensions = glam::UVec2::new(w as _, h as _); @@ -325,11 +326,24 @@ impl ImagesPart { let radius_scale = *properties.backproject_radius_scale.get(); let point_radius_from_world_depth = radius_scale * point_radius_from_depth; + let max_data_value = if let Some((_min, max)) = ctx.cache.tensor_stats(tensor).range { + max as f32 + } else { + // This could only happen for Jpegs, and we should never get here. + // TODO(emilk): refactor the code so that we can always clauclate a range for the tensor + re_log::warn_once!("Couldn't calculate range for a depth tensor!?"); + match data { + DepthCloudDepthData::U16(_) => u16::MAX as f32, + DepthCloudDepthData::F32(_) => 10.0, + } + }; + scene.primitives.depth_clouds.push(DepthCloud { world_from_obj, depth_camera_intrinsics: intrinsics.image_from_cam.into(), - world_depth_from_data_depth: 1.0 / depth_from_world_scale, + world_depth_from_data_depth, point_radius_from_world_depth, + max_depth: world_depth_from_data_depth * max_data_value, depth_dimensions: dimensions, depth_data: data, colormap, From 2c72031c389198271897985fc05d506b66caafb9 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 11:41:19 +0100 Subject: [PATCH 22/29] Fix the gamma of the wgsl color map --- crates/re_renderer/shader/colormap.wgsl | 25 +++++++++++++++++----- crates/re_renderer/shader/depth_cloud.wgsl | 2 +- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/crates/re_renderer/shader/colormap.wgsl b/crates/re_renderer/shader/colormap.wgsl index f177a6959bd1..6c99dac97ebb 100644 --- a/crates/re_renderer/shader/colormap.wgsl +++ b/crates/re_renderer/shader/colormap.wgsl @@ -9,6 +9,9 @@ const COLORMAP_PLASMA: u32 = 3u; const COLORMAP_MAGMA: u32 = 4u; const COLORMAP_INFERNO: u32 = 5u; +/// Returns a gamma-space sRGB in 0-1 range. +/// +/// The input will be saturated to [0, 1] range. fn colormap_srgb(which: u32, t: f32) -> Vec3 { if which == COLORMAP_TURBO { return colormap_turbo_srgb(t); @@ -25,6 +28,13 @@ fn colormap_srgb(which: u32, t: f32) -> Vec3 { } } +/// Returns a linear-space sRGB in 0-1 range. +/// +/// The input will be saturated to [0, 1] range. +fn colormap_linear(which: u32, t: f32) -> Vec3 { + return linear_from_srgb(colormap_srgb(which, t)); +} + // --- Turbo color map --- // Polynomial approximation in GLSL for the Turbo colormap. @@ -38,7 +48,8 @@ fn colormap_srgb(which: u32, t: f32) -> Vec3 { // Colormap Design: Anton Mikhailov (mikhailov@google.com) // GLSL Approximation: Ruofei Du (ruofei@google.com) -/// Returns a normalized sRGB polynomial approximation from Turbo color map, assuming `t` is +/// Returns a gamma-space sRGB in 0-1 range. +/// This is a polynomial approximation from Turbo color map, assuming `t` is /// normalized (it will be saturated no matter what). fn colormap_turbo_srgb(t: f32) -> Vec3 { let r4 = Vec4(0.13572138, 4.61539260, -42.66032258, 132.13108234); @@ -73,7 +84,8 @@ fn colormap_turbo_srgb(t: f32) -> Vec3 { // // Data fitted from https://github.com/BIDS/colormap/blob/master/colormaps.py (CC0). -/// Returns a normalized sRGB polynomial approximation from Viridis color map, assuming `t` is +/// Returns a gamma-space sRGB in 0-1 range. +/// This is a polynomial approximation from Viridis color map, assuming `t` is /// normalized (it will be saturated no matter what). fn colormap_viridis_srgb(t: f32) -> Vec3 { let c0 = Vec3(0.2777273272234177, 0.005407344544966578, 0.3340998053353061); @@ -87,7 +99,8 @@ fn colormap_viridis_srgb(t: f32) -> Vec3 { return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6))))); } -/// Returns a normalized sRGB polynomial approximation from Plasma color map, assuming `t` is +/// Returns a gamma-space sRGB in 0-1 range. +/// This is a polynomial approximation from Plasma color map, assuming `t` is /// normalized (it will be saturated no matter what). fn colormap_plasma_srgb(t: f32) -> Vec3 { let c0 = Vec3(0.05873234392399702, 0.02333670892565664, 0.5433401826748754); @@ -101,7 +114,8 @@ fn colormap_plasma_srgb(t: f32) -> Vec3 { return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6))))); } -/// Returns a normalized sRGB polynomial approximation from Magma color map, assuming `t` is +/// Returns a gamma-space sRGB in 0-1 range. +/// This is a polynomial approximation from Magma color map, assuming `t` is /// normalized (it will be saturated no matter what). fn colormap_magma_srgb(t: f32) -> Vec3 { let c0 = Vec3(-0.002136485053939582, -0.000749655052795221, -0.005386127855323933); @@ -115,7 +129,8 @@ fn colormap_magma_srgb(t: f32) -> Vec3 { return c0 + t * (c1 + t * (c2 + t * (c3 + t * (c4 + t * (c5 + t * c6))))); } -/// Returns a normalized sRGB polynomial approximation from Inferno color map, assuming `t` is +/// Returns a gamma-space sRGB in 0-1 range. +/// This is a polynomial approximation from Inferno color map, assuming `t` is /// normalized (it will be saturated no matter what). fn colormap_inferno_srgb(t: f32) -> Vec3 { let c0 = Vec3(0.0002189403691192265, 0.001651004631001012, -0.01948089843709184); diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index 8c508a3e988d..51bcf0b19cae 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -28,7 +28,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { let world_space_depth = depth_cloud_info.world_depth_from_texture_value * textureLoad(depth_texture, texcoords, 0).x; // TODO(cmc): albedo textures - let color = Vec4(colormap_srgb(depth_cloud_info.colormap, world_space_depth / depth_cloud_info.max_depth), 1.0); + let color = Vec4(colormap_linear(depth_cloud_info.colormap, world_space_depth / depth_cloud_info.max_depth), 1.0); // TODO(cmc): This assumes a pinhole camera; need to support other kinds at some point. let intrinsics = depth_cloud_info.depth_camera_intrinsics; From 8134e8ac37d8b804cfc1841ec4bf2b9647c6b881 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 11:55:32 +0100 Subject: [PATCH 23/29] =?UTF-8?q?Tweak=20default=20point=20radius=20to=20a?= =?UTF-8?q?void=20Moir=C3=A9=20patterns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/re_data_store/src/entity_properties.rs | 4 +--- crates/re_renderer/src/renderer/depth_cloud.rs | 2 +- crates/re_viewer/src/ui/selection_panel.rs | 10 +++++----- .../src/ui/view_spatial/scene/scene_part/images.rs | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 4757f4ec4a44..70c72bbc21f5 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -72,8 +72,6 @@ pub struct EntityProperties { pub depth_from_world_scale: EditableAutoValue, /// Used to scale the radii of the points in the resulting point cloud. - /// - /// Default is 1.0. pub backproject_radius_scale: EditableAutoValue, } @@ -122,7 +120,7 @@ impl Default for EntityProperties { backproject_depth: false, backproject_pinhole_ent_path: None, depth_from_world_scale: EditableAutoValue::default(), - backproject_radius_scale: EditableAutoValue::Auto(1.0), + backproject_radius_scale: EditableAutoValue::Auto(2.0), // Lower values leads to too much Moiré } } } diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 58de62d3383b..d479219e9460 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -134,7 +134,7 @@ pub struct DepthCloud { /// Only supports pinhole cameras at the moment. pub depth_camera_intrinsics: glam::Mat3, - /// Multiplier to get world-space depth from whatever is in [`depth_data`]. + /// Multiplier to get world-space depth from whatever is in [`Self::depth_data`]. pub world_depth_from_data_depth: f32, /// Point radius is calculated as world-space depth times this value. diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index ce637295cf5d..8f65d9e4e823 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -548,8 +548,8 @@ fn depth_from_world_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoValue .clamp_range(0.0..=1.0e8) .speed(speed), ) - .on_hover_text("How many steps in the depth image correspond to one world-space unit. For instance, 1000 means millimeters.\ - \nDouble-click to reset."); + .on_hover_text("How many steps in the depth image correspond to one world-space unit. For instance, 1000 means millimeters.\n\ + Double-click to reset."); if response.double_clicked() { // reset to auto - the exact value will be restored somewhere else *property = EditableAutoValue::Auto(value); @@ -572,11 +572,11 @@ fn backproject_radius_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoVal ) .on_hover_text( "Scales the radii of the points in the backprojected point cloud.\n\ - With a scale of one, diagonally adjacent pixels at the same depth are sized so that they are just touching, leaving no gaps.\ - \nDouble-click to reset.", + With a scale of one, adjacent pixels at the same depth are sized so that they are just touching.\ + \nDouble-click to reset.", ); if response.double_clicked() { - *property = EditableAutoValue::Auto(1.0); + *property = EditableAutoValue::Auto(2.0); response.surrender_focus(); } else if response.changed() { *property = EditableAutoValue::UserEdited(value); diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 997b52751920..38a889250fe0 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -318,11 +318,11 @@ impl ImagesPart { }; // By default, we assign a radius to each point so that each point becomes a ball - // that just barely touches its diagonally-neighboring pixel-point. + // that just barely touches its neighboring pixel-points. // This means the point radius increases with distance. // It also increases with the field of view, and decreases with the resolution. let fov_y = intrinsics.fov_y().unwrap_or(1.0); - let point_radius_from_depth = 0.5_f32.sqrt() * (0.5 * fov_y).tan() / (0.5 * h as f32); + let point_radius_from_depth = (0.5 * fov_y).tan() / (0.5 * h as f32); let radius_scale = *properties.backproject_radius_scale.get(); let point_radius_from_world_depth = radius_scale * point_radius_from_depth; From f489b2af1813f390412be3a33533dbf42eae7f35 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 12:03:37 +0100 Subject: [PATCH 24/29] Final touches --- crates/re_data_store/src/entity_properties.rs | 2 +- crates/re_viewer/src/ui/selection_panel.rs | 5 +++-- .../src/ui/view_spatial/scene/scene_part/images.rs | 11 +++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/re_data_store/src/entity_properties.rs b/crates/re_data_store/src/entity_properties.rs index 70c72bbc21f5..0ecee09e2a95 100644 --- a/crates/re_data_store/src/entity_properties.rs +++ b/crates/re_data_store/src/entity_properties.rs @@ -120,7 +120,7 @@ impl Default for EntityProperties { backproject_depth: false, backproject_pinhole_ent_path: None, depth_from_world_scale: EditableAutoValue::default(), - backproject_radius_scale: EditableAutoValue::Auto(2.0), // Lower values leads to too much Moiré + backproject_radius_scale: EditableAutoValue::Auto(1.0), } } } diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index 8f65d9e4e823..ac6645f52cf8 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -572,8 +572,9 @@ fn backproject_radius_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoVal ) .on_hover_text( "Scales the radii of the points in the backprojected point cloud.\n\ - With a scale of one, adjacent pixels at the same depth are sized so that they are just touching.\ - \nDouble-click to reset.", + This is a factor of the projected pixel diameter. \ + This means a scale of 0.5 will leave adjacent pixels at the same depth value jsut touching.\n\ + Double-click to reset.", ); if response.double_clicked() { *property = EditableAutoValue::Auto(2.0); diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 38a889250fe0..5bd508dd5676 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -317,14 +317,13 @@ impl ImagesPart { }, }; - // By default, we assign a radius to each point so that each point becomes a ball - // that just barely touches its neighboring pixel-points. - // This means the point radius increases with distance. - // It also increases with the field of view, and decreases with the resolution. + // We want point radius to be defined in a scale where the radius of a point + // is a factor (`backproject_radius_scale`) of the diameter of a pixel projected + // at that distance. let fov_y = intrinsics.fov_y().unwrap_or(1.0); - let point_radius_from_depth = (0.5 * fov_y).tan() / (0.5 * h as f32); + let pixel_width_from_depth = (0.5 * fov_y).tan() / (0.5 * h as f32); let radius_scale = *properties.backproject_radius_scale.get(); - let point_radius_from_world_depth = radius_scale * point_radius_from_depth; + let point_radius_from_world_depth = radius_scale * pixel_width_from_depth; let max_data_value = if let Some((_min, max)) = ctx.cache.tensor_stats(tensor).range { max as f32 From e321037562fc423f0ec9d8aa8e3056ebfaa7e62a Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 12:04:25 +0100 Subject: [PATCH 25/29] spell fix --- crates/re_viewer/src/ui/selection_panel.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_viewer/src/ui/selection_panel.rs b/crates/re_viewer/src/ui/selection_panel.rs index ac6645f52cf8..a7b1b3e4a3b6 100644 --- a/crates/re_viewer/src/ui/selection_panel.rs +++ b/crates/re_viewer/src/ui/selection_panel.rs @@ -573,7 +573,7 @@ fn backproject_radius_scale_ui(ui: &mut egui::Ui, property: &mut EditableAutoVal .on_hover_text( "Scales the radii of the points in the backprojected point cloud.\n\ This is a factor of the projected pixel diameter. \ - This means a scale of 0.5 will leave adjacent pixels at the same depth value jsut touching.\n\ + This means a scale of 0.5 will leave adjacent pixels at the same depth value just touching.\n\ Double-click to reset.", ); if response.double_clicked() { From f2e148449dddae3fd660838b6ea06e631da59a3c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 13:34:13 +0100 Subject: [PATCH 26/29] more typos Co-authored-by: Andreas Reich --- crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 5bd508dd5676..2e0b365ce263 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -329,7 +329,7 @@ impl ImagesPart { max as f32 } else { // This could only happen for Jpegs, and we should never get here. - // TODO(emilk): refactor the code so that we can always clauclate a range for the tensor + // TODO(emilk): refactor the code so that we can always calculate a range for the tensor re_log::warn_once!("Couldn't calculate range for a depth tensor!?"); match data { DepthCloudDepthData::U16(_) => u16::MAX as f32, From 21cfdcf5e46f12c5b974a634f6186331808a8d09 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 13:43:21 +0100 Subject: [PATCH 27/29] Fix comment about why we use Depth16Unorm --- crates/re_renderer/src/renderer/depth_cloud.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index d479219e9460..8a727cdc7dd3 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -229,8 +229,7 @@ impl DepthCloudDrawData { wgpu::TextureFormat::R32Float, ) } else { - // Native: We use Depth16Unorm over R16Unorm because the latter is behind a feature flag, - // and not available on OpenGL backends. + // Native: We use Depth16Unorm over R16Unorm because the latter is behind a feature flag and doesn't work on WebGPU. create_and_upload_texture( ctx, depth_cloud, From ea8c05e87232ae42023c04614b24db101308e9a2 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 13:43:34 +0100 Subject: [PATCH 28/29] Add lines to changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7bc16827a65..c9e58b70b1eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## Unreleased [Commits since latest release](https://github.com/rerun-io/rerun/compare/latest...HEAD) +* Fixed a bug in the image hover code, causing the wrong RGBA values to be printed 😬 [#1690](https://github.com/rerun-io/rerun/pull/1356) +* Fixed a bug that caused points to be render too large [#1690](https://github.com/rerun-io/rerun/pull/1690) ## 0.3.1 - Remove potentially sensitive analytics [Commits](https://github.com/rerun-io/rerun/compare/v0.3.1...v0.3.0) From ca8b777ba0cf19de1e520b64b7799820bff8f157 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 24 Mar 2023 13:53:47 +0100 Subject: [PATCH 29/29] max_depth -> max_depth_in_world --- crates/re_renderer/examples/depth_cloud.rs | 2 +- crates/re_renderer/shader/depth_cloud.wgsl | 6 +++--- crates/re_renderer/src/renderer/depth_cloud.rs | 12 ++++++------ .../src/ui/view_spatial/scene/scene_part/images.rs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/re_renderer/examples/depth_cloud.rs b/crates/re_renderer/examples/depth_cloud.rs index b40e93b35ab7..c7a86f431da9 100644 --- a/crates/re_renderer/examples/depth_cloud.rs +++ b/crates/re_renderer/examples/depth_cloud.rs @@ -177,7 +177,7 @@ impl RenderDepthClouds { depth_camera_intrinsics: *intrinsics, world_depth_from_data_depth: 1.0, point_radius_from_world_depth: *point_radius_from_world_depth, - max_depth: 5.0, + max_depth_in_world: 5.0, depth_dimensions: depth.dimensions, depth_data: depth.data.clone(), colormap: re_renderer::ColorMap::ColorMapTurbo, diff --git a/crates/re_renderer/shader/depth_cloud.wgsl b/crates/re_renderer/shader/depth_cloud.wgsl index 51bcf0b19cae..c2db9823e97f 100644 --- a/crates/re_renderer/shader/depth_cloud.wgsl +++ b/crates/re_renderer/shader/depth_cloud.wgsl @@ -28,7 +28,7 @@ fn compute_point_data(quad_idx: i32) -> PointData { let world_space_depth = depth_cloud_info.world_depth_from_texture_value * textureLoad(depth_texture, texcoords, 0).x; // TODO(cmc): albedo textures - let color = Vec4(colormap_linear(depth_cloud_info.colormap, world_space_depth / depth_cloud_info.max_depth), 1.0); + let color = Vec4(colormap_linear(depth_cloud_info.colormap, world_space_depth / depth_cloud_info.max_depth_in_world), 1.0); // TODO(cmc): This assumes a pinhole camera; need to support other kinds at some point. let intrinsics = depth_cloud_info.depth_camera_intrinsics; @@ -71,8 +71,8 @@ struct DepthCloudInfo { /// Point radius is calculated as world-space depth times this value. point_radius_from_world_depth: f32, - /// The maximum depth value, for use with the colormap. - max_depth: f32, + /// The maximum depth value in world-space, for use with the colormap. + max_depth_in_world: f32, /// Configures color mapping mode, see `colormap.wgsl`. colormap: u32, diff --git a/crates/re_renderer/src/renderer/depth_cloud.rs b/crates/re_renderer/src/renderer/depth_cloud.rs index 8a727cdc7dd3..561117bba46c 100644 --- a/crates/re_renderer/src/renderer/depth_cloud.rs +++ b/crates/re_renderer/src/renderer/depth_cloud.rs @@ -54,8 +54,8 @@ mod gpu_data { /// Point radius is calculated as world-space depth times this value. pub point_radius_from_world_depth: f32, - /// The maximum depth value, for use with the colormap. - pub max_depth: f32, + /// The maximum depth value in world-space, for use with the colormap. + pub max_depth_in_world: f32, pub colormap: u32, pub row_pad: [u32; 2], @@ -70,7 +70,7 @@ mod gpu_data { depth_camera_intrinsics, world_depth_from_data_depth, point_radius_from_world_depth, - max_depth, + max_depth_in_world, depth_dimensions: _, depth_data, colormap, @@ -90,7 +90,7 @@ mod gpu_data { outline_mask_id: outline_mask_id.0.unwrap_or_default().into(), world_depth_from_texture_value, point_radius_from_world_depth: *point_radius_from_world_depth, - max_depth: *max_depth, + max_depth_in_world: *max_depth_in_world, colormap: *colormap as u32, row_pad: Default::default(), end_padding: Default::default(), @@ -140,8 +140,8 @@ pub struct DepthCloud { /// Point radius is calculated as world-space depth times this value. pub point_radius_from_world_depth: f32, - /// The maximum depth value, for use with the colormap. - pub max_depth: f32, + /// The maximum depth value in world-space, for use with the colormap. + pub max_depth_in_world: f32, /// The dimensions of the depth texture in pixels. pub depth_dimensions: glam::UVec2, diff --git a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs index 2e0b365ce263..b92d66297804 100644 --- a/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs +++ b/crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs @@ -342,7 +342,7 @@ impl ImagesPart { depth_camera_intrinsics: intrinsics.image_from_cam.into(), world_depth_from_data_depth, point_radius_from_world_depth, - max_depth: world_depth_from_data_depth * max_data_value, + max_depth_in_world: world_depth_from_data_depth * max_data_value, depth_dimensions: dimensions, depth_data: data, colormap,