Skip to content

Commit

Permalink
Integrate GPU color maps into depth clouds (#1486)
Browse files Browse the repository at this point in the history
* integrate color maps into depth clouds

* clean mess

* pad
  • Loading branch information
teh-cmc authored Mar 3, 2023
1 parent 2a73bfc commit b64a438
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 11 deletions.
62 changes: 61 additions & 1 deletion crates/re_data_store/src/entity_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ pub struct EntityProperties {
pub visible_history: ExtraQueryHistory,
pub interactive: bool,

/// Enable color mapping?
///
/// See [`Self::color_mapper`] to select an actual mapping.
pub color_mapping: bool,
/// What kind of color mapping should be applied (none, map, texture, transfer..)?
pub color_mapper: EditableAutoValue<ColorMapper>,

/// Distance of the projection plane (frustum far plane).
///
/// Only applies to pinhole cameras when in a spatial view, using 3D navigation.
///
pub pinhole_image_plane_distance: EditableAutoValue<f32>,

/// Should the depth texture be backprojected into a point cloud?
Expand All @@ -76,10 +82,15 @@ impl EntityProperties {
visible: self.visible && child.visible,
visible_history: self.visible_history.with_child(&child.visible_history),
interactive: self.interactive && child.interactive,

color_mapping: self.color_mapping || child.color_mapping,
color_mapper: self.color_mapper.or(&child.color_mapper).clone(),

pinhole_image_plane_distance: self
.pinhole_image_plane_distance
.or(&child.pinhole_image_plane_distance)
.clone(),

backproject_depth: self.backproject_depth || child.backproject_depth,
backproject_pinhole_ent_path: self
.backproject_pinhole_ent_path
Expand All @@ -101,6 +112,8 @@ impl Default for EntityProperties {
visible: true,
visible_history: ExtraQueryHistory::default(),
interactive: true,
color_mapping: false,
color_mapper: EditableAutoValue::default(),
pinhole_image_plane_distance: EditableAutoValue::default(),
backproject_depth: false,
backproject_pinhole_ent_path: None,
Expand Down Expand Up @@ -133,6 +146,53 @@ impl ExtraQueryHistory {
sequences: self.sequences.max(child.sequences),
}
}
} // ----------------------------------------------------------------------------

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ColorMap {
Grayscale,
Turbo,
Viridis,
Plasma,
Magma,
Inferno,
}

impl std::fmt::Display for ColorMap {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
ColorMap::Grayscale => "Grayscale",
ColorMap::Turbo => "Turbo",
ColorMap::Viridis => "Viridis",
ColorMap::Plasma => "Plasma",
ColorMap::Magma => "Magma",
ColorMap::Inferno => "Inferno",
})
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ColorMapper {
/// Use a well-known color map, pre-implemented as a wgsl module.
ColorMap(ColorMap),
// TODO(cmc): support textures.
// TODO(cmc): support custom transfer functions.
}

impl std::fmt::Display for ColorMapper {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ColorMapper::ColorMap(colormap) => colormap.fmt(f),
}
}
}

impl Default for ColorMapper {
fn default() -> Self {
Self::ColorMap(ColorMap::Grayscale)
}
}

// ----------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions crates/re_renderer/examples/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ impl RenderDepthClouds {
radius_scale: *radius_scale,
depth_dimensions: depth.dimensions,
depth_data: depth.data.clone(),
colormap: re_renderer::ColorMap::ColorMapTurbo,
}],
)
.unwrap();
Expand Down
10 changes: 5 additions & 5 deletions crates/re_renderer/shader/colormap.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ const COLORMAP_INFERNO: u32 = 5u;

fn colormap_srgb(which: u32, t: f32) -> Vec3 {
if which == COLORMAP_TURBO {
return colormap_turbo(t);
return colormap_turbo_srgb(t);
} else if which == COLORMAP_VIRIDIS {
return colormap_viridis(t);
return colormap_viridis_srgb(t);
} else if which == COLORMAP_PLASMA {
return colormap_plasma(t);
return colormap_plasma_srgb(t);
} else if which == COLORMAP_MAGMA {
return colormap_magma(t);
return colormap_magma_srgb(t);
} else if which == COLORMAP_INFERNO {
return colormap_inferno(t);
return colormap_inferno_srgb(t);
} else { // assume grayscale
return linear_from_srgb(Vec3(t));
}
Expand Down
11 changes: 9 additions & 2 deletions crates/re_renderer/shader/depth_cloud.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//!
//! See `src/renderer/depth_cloud.rs` for more documentation.

#import <./colormap.wgsl>
#import <./global_bindings.wgsl>
#import <./types.wgsl>
#import <./utils/camera.wgsl>
Expand All @@ -26,8 +27,8 @@ fn compute_point_data(quad_idx: i32) -> PointData {
// TODO(cmc): expose knobs to linearize/normalize/flip/cam-to-plane depth.
let norm_linear_depth = textureLoad(depth_texture, texcoords, 0).x;

// TODO(cmc): support color maps & albedo textures
let color = Vec4(linear_from_srgb(Vec3(norm_linear_depth)), 1.0);
// TODO(cmc): albedo textures
let color = Vec4(colormap_srgb(depth_cloud_info.colormap, norm_linear_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;
Expand Down Expand Up @@ -62,6 +63,12 @@ struct DepthCloudInfo {

/// The scale to apply to the radii of the backprojected points.
radius_scale: f32,
radius_scale_row_pad0: f32,
radius_scale_row_pad1: f32,
radius_scale_row_pad2: f32,

/// Configures color mapping mode, see `colormap.wgsl`.
colormap: u32,
};
@group(1) @binding(0)
var<uniform> depth_cloud_info: DepthCloudInfo;
Expand Down
9 changes: 8 additions & 1 deletion crates/re_renderer/src/renderer/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
GpuRenderPipelineHandle, GpuTexture, PipelineLayoutDesc, RenderPipelineDesc,
ShaderModuleDesc, TextureDesc,
},
ColorMap,
};

use super::{
Expand All @@ -42,8 +43,9 @@ mod gpu_data {
pub depth_camera_extrinsics: crate::wgpu_buffer_types::Mat4,
pub depth_camera_intrinsics: crate::wgpu_buffer_types::Mat3,
pub radius_scale: crate::wgpu_buffer_types::F32RowPadded,
pub colormap: crate::wgpu_buffer_types::U32RowPadded,

pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 8],
pub end_padding: [crate::wgpu_buffer_types::PaddingRow; 16 - 9],
}
}

Expand Down Expand Up @@ -89,6 +91,9 @@ pub struct DepthCloud {
///
/// See [`DepthCloudDepthData`] for more information.
pub depth_data: DepthCloudDepthData,

/// Configures color mapping mode.
pub colormap: ColorMap,
}

impl Default for DepthCloud {
Expand All @@ -99,6 +104,7 @@ impl Default for DepthCloud {
radius_scale: 1.0,
depth_dimensions: glam::UVec2::ZERO,
depth_data: DepthCloudDepthData::default(),
colormap: ColorMap::ColorMapTurbo,
}
}
}
Expand Down Expand Up @@ -144,6 +150,7 @@ impl DepthCloudDrawData {
depth_camera_extrinsics: info.depth_camera_extrinsics.into(),
depth_camera_intrinsics: info.depth_camera_intrinsics.into(),
radius_scale: info.radius_scale.into(),
colormap: (info.colormap as u32).into(),
end_padding: Default::default(),
}),
);
Expand Down
47 changes: 46 additions & 1 deletion crates/re_viewer/src/ui/selection_panel.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use egui::NumExt as _;
use re_data_store::{query_latest_single, EditableAutoValue, EntityPath, EntityProperties};
use re_data_store::{
query_latest_single, ColorMap, ColorMapper, EditableAutoValue, EntityPath, EntityProperties,
};
use re_log_types::{
component_types::{Tensor, TensorDataMeaning},
TimeType, Transform,
Expand Down Expand Up @@ -418,6 +420,45 @@ fn entity_props_ui(
});
}

fn colormap_props_ui(ui: &mut egui::Ui, entity_props: &mut EntityProperties) {
ui.checkbox(&mut entity_props.color_mapping, "Color mapping")
.on_hover_text("Toggles color mapping");
ui.end_row();

if !entity_props.color_mapping {
return;
}

let current = *entity_props.color_mapper.get();

ui.label("Color map");
egui::ComboBox::from_id_source("color_mapper")
.selected_text(current.to_string())
.show_ui(ui, |ui| {
ui.style_mut().wrap = Some(false);
ui.set_min_width(64.0);

// TODO(cmc): that is not ideal but I don't want to import yet another proc-macro...
let mut add_label = |proposed| {
if ui
.selectable_label(current == proposed, proposed.to_string())
.clicked()
{
entity_props.color_mapper = EditableAutoValue::Auto(proposed);
}
};

add_label(ColorMapper::ColorMap(ColorMap::Grayscale));
add_label(ColorMapper::ColorMap(ColorMap::Turbo));
add_label(ColorMapper::ColorMap(ColorMap::Viridis));
add_label(ColorMapper::ColorMap(ColorMap::Plasma));
add_label(ColorMapper::ColorMap(ColorMap::Magma));
add_label(ColorMapper::ColorMap(ColorMap::Inferno));
});

ui.end_row();
}

fn pinhole_props_ui(
ctx: &mut ViewerContext<'_>,
ui: &mut egui::Ui,
Expand Down Expand Up @@ -520,6 +561,10 @@ fn depth_props_ui(
entity_props.backproject_radius_scale = EditableAutoValue::UserEdited(radius_scale);
}
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.
colormap_props_ui(ui, entity_props);
} else {
entity_props.backproject_pinhole_ent_path = None;
}
Expand Down
17 changes: 16 additions & 1 deletion crates/re_viewer/src/ui/view_spatial/scene/scene_part/images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use re_log_types::{
use re_query::{query_primary_with_history, EntityView, QueryError};
use re_renderer::{
renderer::{DepthCloud, DepthCloudDepthData},
Size,
ColorMap, Size,
};

use crate::{
Expand Down Expand Up @@ -307,12 +307,27 @@ impl ImagesPart {

let world_from_obj = extrinsics * glam::Mat4::from_scale(glam::Vec3::splat(scale));

let colormap = properties
.color_mapping
.then(|| match *properties.color_mapper.get() {
re_data_store::ColorMapper::ColorMap(colormap) => match colormap {
re_data_store::ColorMap::Grayscale => ColorMap::Grayscale,
re_data_store::ColorMap::Turbo => ColorMap::ColorMapTurbo,
re_data_store::ColorMap::Viridis => ColorMap::ColorMapViridis,
re_data_store::ColorMap::Plasma => ColorMap::ColorMapPlasma,
re_data_store::ColorMap::Magma => ColorMap::ColorMapMagma,
re_data_store::ColorMap::Inferno => ColorMap::ColorMapInferno,
},
})
.unwrap_or(ColorMap::Grayscale);

scene.primitives.depth_clouds.push(DepthCloud {
depth_camera_extrinsics: world_from_obj,
depth_camera_intrinsics: intrinsics.image_from_cam.into(),
radius_scale,
depth_dimensions: dimensions,
depth_data: data,
colormap,
});
}
}
Expand Down

1 comment on commit b64a438

@github-actions
Copy link

Choose a reason for hiding this comment

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

Rust Benchmark

Benchmark suite Current: b64a438 Previous: 2a73bfc Ratio
datastore/insert/batch/rects/insert 536865 ns/iter (± 6681) 565168 ns/iter (± 1877) 0.95
datastore/latest_at/batch/rects/query 1753 ns/iter (± 33) 1804 ns/iter (± 5) 0.97
datastore/latest_at/missing_components/primary 351 ns/iter (± 3) 355 ns/iter (± 0) 0.99
datastore/latest_at/missing_components/secondaries 409 ns/iter (± 6) 428 ns/iter (± 0) 0.96
datastore/range/batch/rects/query 147141 ns/iter (± 2044) 152456 ns/iter (± 814) 0.97
mono_points_arrow/generate_message_bundles 44677730 ns/iter (± 2185080) 49064975 ns/iter (± 806644) 0.91
mono_points_arrow/generate_messages 132935163 ns/iter (± 2315847) 135449236 ns/iter (± 1159893) 0.98
mono_points_arrow/encode_log_msg 157698141 ns/iter (± 2074223) 165556376 ns/iter (± 647784) 0.95
mono_points_arrow/encode_total 340888429 ns/iter (± 15071023) 353700751 ns/iter (± 1912123) 0.96
mono_points_arrow/decode_log_msg 178099690 ns/iter (± 1980460) 187230488 ns/iter (± 976768) 0.95
mono_points_arrow/decode_message_bundles 69823066 ns/iter (± 1286453) 71706122 ns/iter (± 955326) 0.97
mono_points_arrow/decode_total 250054987 ns/iter (± 4888657) 258693886 ns/iter (± 2438180) 0.97
batch_points_arrow/generate_message_bundles 330663 ns/iter (± 4384) 332332 ns/iter (± 558) 0.99
batch_points_arrow/generate_messages 6089 ns/iter (± 95) 6258 ns/iter (± 20) 0.97
batch_points_arrow/encode_log_msg 351095 ns/iter (± 1957) 357649 ns/iter (± 583) 0.98
batch_points_arrow/encode_total 698518 ns/iter (± 4328) 712625 ns/iter (± 1627) 0.98
batch_points_arrow/decode_log_msg 345064 ns/iter (± 2016) 349032 ns/iter (± 504) 0.99
batch_points_arrow/decode_message_bundles 2026 ns/iter (± 23) 2068 ns/iter (± 7) 0.98
batch_points_arrow/decode_total 351978 ns/iter (± 3413) 355541 ns/iter (± 982) 0.99
arrow_mono_points/insert 6940741020 ns/iter (± 26143715) 6972401497 ns/iter (± 39579228) 1.00
arrow_mono_points/query 1706588 ns/iter (± 37725) 1774283 ns/iter (± 9050) 0.96
arrow_batch_points/insert 2623148 ns/iter (± 22440) 2680902 ns/iter (± 8792) 0.98
arrow_batch_points/query 15408 ns/iter (± 218) 16104 ns/iter (± 19) 0.96
arrow_batch_vecs/insert 41986 ns/iter (± 521) 41778 ns/iter (± 84) 1.00
arrow_batch_vecs/query 505953 ns/iter (± 2479) 506173 ns/iter (± 389) 1.00
tuid/Tuid::random 34 ns/iter (± 0) 34 ns/iter (± 0) 1

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

Please sign in to comment.