Skip to content

Commit

Permalink
Configurable background color for 3D Space Views (#5443)
Browse files Browse the repository at this point in the history
### What

* Fixes  #754

Originally made a sort of tint/alpha color for the existing gradient,
but after some feedback I got I changed it around to be a dropdown of 3
different modes: dark gradient, bright gradient, solid color (with the
picker)
The blend version was quite confusing and admittedly not all that useful
:)



https://github.com/rerun-io/rerun/assets/1220815/2ed21cba-3abe-46f1-9ce3-317f41e576d4



### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using newly built examples:
[app.rerun.io](https://app.rerun.io/pr/5443/index.html)
* Using examples from latest `main` build:
[app.rerun.io](https://app.rerun.io/pr/5443/index.html?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[app.rerun.io](https://app.rerun.io/pr/5443/index.html?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/5443)
- [Docs
preview](https://rerun.io/preview/5088b46141a6c8823ebe8cd51e112b49c47a165d/docs)
<!--DOCS-PREVIEW-->
- [Examples
preview](https://rerun.io/preview/5088b46141a6c8823ebe8cd51e112b49c47a165d/examples)
<!--EXAMPLES-PREVIEW-->
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)
  • Loading branch information
Wumpf authored Mar 12, 2024
1 parent 124305c commit 7a6efff
Show file tree
Hide file tree
Showing 39 changed files with 1,250 additions and 159 deletions.
8 changes: 2 additions & 6 deletions crates/re_data_ui/src/editors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ fn edit_color_ui(
.ok()
.unwrap_or_else(|| default_color(ctx, query, store, entity_path));

let [r, g, b, a] = current_color.to_array();
let current_color = egui::Color32::from_rgba_unmultiplied(r, g, b, a);
let current_color = current_color.into();
let mut edit_color = current_color;

egui::color_picker::color_edit_button_srgba(
Expand All @@ -42,10 +41,7 @@ fn edit_color_ui(
);

if edit_color != current_color {
let [r, g, b, a] = edit_color.to_array();
let new_color = Color::from_unmultiplied_rgba(r, g, b, a);

ctx.save_blueprint_component(override_path, &new_color);
ctx.save_blueprint_component(override_path, &Color::from(edit_color));
}
}

Expand Down
27 changes: 22 additions & 5 deletions crates/re_renderer/shader/generic_skybox.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,26 @@
#import <./utils/camera.wgsl>
#import <./screen_triangle_vertex.wgsl>

struct UniformBuffer {
// See `GenericSkyboxType` in `generic_skybox.rs`
background_type: u32,
_padding: vec3f,
}

const GRADIENT_DARK: u32 = 0u;
const GRADIENT_BRGHT: u32 = 1u;

@group(1) @binding(0)
var<uniform> uniforms: UniformBuffer;

fn skybox_dark_srgb(dir: vec3f) -> vec3f {
let rgb = dir * 0.5 + vec3f(0.5);
return vec3f(0.05) + 0.20 * rgb;
}

fn skybox_light_srgb(dir: vec3f) -> vec3f {
let rgb = dir * 0.5 + vec3f(0.5);
return vec3f(0.85) + 0.15 * rgb;
return vec3f(0.7) + 0.20 * rgb;
}

// -----------------------------------------------
Expand Down Expand Up @@ -39,15 +51,20 @@ fn dither_interleaved(rgb: vec3f, levels: f32, frag_coord: vec4<f32>) -> vec3f {
@fragment
fn main(in: FragmentInput, @builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4f {
let camera_dir = camera_ray_direction_from_screenuv(in.texcoord);
// Messing with direction a bit so it looks like in our old three-d based renderer (for easier comparison)
let rgb = skybox_dark_srgb(camera_dir); // TODO(andreas): Allow switching to skybox_light

var rgb: vec3f;
if uniforms.background_type == GRADIENT_DARK {
rgb = skybox_dark_srgb(camera_dir);
} else {
rgb = skybox_light_srgb(camera_dir);
}

// Apply dithering in gamma space.
// TODO(andreas): Once we switch to HDR outputs, this can be removed.
// As of writing, the render target itself is (s)RGB8, so we need to dither while we still have maximum precision.
let rgb_dithered = dither_interleaved(rgb, 256.0, frag_coord);
var rgb_gamma_dithered = dither_interleaved(rgb, 256.0, frag_coord);

return vec4f(linear_from_srgb(rgb_dithered), 1.0);
return vec4f(linear_from_srgb(rgb_gamma_dithered), 1.0);
//return vec4f(linear_from_srgb(rgb), 1.0); // Without dithering
//return vec4f(camera_dir, 1.0);
}
82 changes: 75 additions & 7 deletions crates/re_renderer/src/renderer/generic_skybox.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,82 @@
use smallvec::smallvec;

use crate::{
allocator::create_and_fill_uniform_buffer,
draw_phases::DrawPhase,
include_shader_module,
renderer::screen_triangle_vertex_shader,
view_builder::ViewBuilder,
wgpu_resources::{
BindGroupDesc, BindGroupLayoutDesc, GpuBindGroup, GpuBindGroupLayoutHandle,
GpuRenderPipelineHandle, GpuRenderPipelinePoolAccessor, PipelineLayoutDesc,
RenderPipelineDesc,
},
};

use super::{DrawData, DrawError, RenderContext, Renderer};

/// The type of generic skybox to render.
///
/// If you want a solid background color, don't add the skybox at all and instead set a clear color.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum GenericSkyboxType {
#[default]
GradientDark = 0,
GradientBright = 1,
}

mod gpu_data {
use crate::wgpu_buffer_types;

#[repr(C, align(256))]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
pub struct UniformBuffer {
pub background_type: wgpu_buffer_types::U32RowPadded,
pub _end_padding: [wgpu_buffer_types::PaddingRow; 16 - 1],
}
}

/// Renders a generated skybox from a color gradient
///
/// Is not actually a skybox, but a fullscreen effect.
/// Should be rendered *last* to reduce amount of overdraw!
pub struct GenericSkybox {
render_pipeline: GpuRenderPipelineHandle,
bind_group_layout: GpuBindGroupLayoutHandle,
}

#[derive(Clone)]
pub struct GenericSkyboxDrawData {}
pub struct GenericSkyboxDrawData {
bind_group: GpuBindGroup,
}

impl DrawData for GenericSkyboxDrawData {
type Renderer = GenericSkybox;
}

impl GenericSkyboxDrawData {
pub fn new(ctx: &RenderContext) -> Self {
let _ = ctx.renderer::<GenericSkybox>(); // TODO(andreas): This line ensures that the renderer exists. Currently this needs to be done ahead of time, but should be fully automatic!
GenericSkyboxDrawData {}
pub fn new(ctx: &RenderContext, typ: GenericSkyboxType) -> Self {
let skybox_renderer = ctx.renderer::<GenericSkybox>();

let uniform_buffer = gpu_data::UniformBuffer {
background_type: (typ as u32).into(),
_end_padding: Default::default(),
};

let uniform_buffer_binding =
create_and_fill_uniform_buffer(ctx, "skybox uniform buffer".into(), uniform_buffer);

let bind_group = ctx.gpu_resources.bind_groups.alloc(
&ctx.device,
&ctx.gpu_resources,
&BindGroupDesc {
label: "GenericSkyboxDrawData::bind_group".into(),
entries: smallvec![uniform_buffer_binding,],
layout: skybox_renderer.bind_group_layout,
},
);

GenericSkyboxDrawData { bind_group }
}
}

Expand All @@ -41,6 +86,25 @@ impl Renderer for GenericSkybox {
fn create_renderer(ctx: &RenderContext) -> Self {
re_tracing::profile_function!();

let bind_group_layout = ctx.gpu_resources.bind_group_layouts.get_or_create(
&ctx.device,
&(BindGroupLayoutDesc {
label: "GenericSkybox::bind_group_layout".into(),
entries: vec![wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: (std::mem::size_of::<gpu_data::UniformBuffer>() as u64)
.try_into()
.ok(),
},
count: None,
}],
}),
);

let vertex_handle = screen_triangle_vertex_shader(ctx);
let render_pipeline = ctx.gpu_resources.render_pipelines.get_or_create(
ctx,
Expand All @@ -50,7 +114,7 @@ impl Renderer for GenericSkybox {
ctx,
&PipelineLayoutDesc {
label: "GenericSkybox::render_pipeline".into(),
entries: vec![ctx.global_bindings.layout],
entries: vec![ctx.global_bindings.layout, bind_group_layout],
},
),

Expand All @@ -76,21 +140,25 @@ impl Renderer for GenericSkybox {
multisample: ViewBuilder::MAIN_TARGET_DEFAULT_MSAA_STATE,
},
);
GenericSkybox { render_pipeline }
GenericSkybox {
render_pipeline,
bind_group_layout,
}
}

fn draw<'a>(
&self,
render_pipelines: &'a GpuRenderPipelinePoolAccessor<'a>,
_phase: DrawPhase,
pass: &mut wgpu::RenderPass<'a>,
_draw_data: &GenericSkyboxDrawData,
draw_data: &'a Self::RendererDrawData,
) -> Result<(), DrawError> {
re_tracing::profile_function!();

let pipeline = render_pipelines.get(self.render_pipeline)?;

pass.set_pipeline(pipeline);
pass.set_bind_group(1, &draw_data.bind_group, &[]);
pass.draw(0..3, 0..1);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer/src/renderer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod generic_skybox;
pub use generic_skybox::GenericSkyboxDrawData;
pub use generic_skybox::{GenericSkyboxDrawData, GenericSkyboxType};

mod lines;
pub use lines::{LineBatchInfo, LineDrawData, LineDrawDataError, LineStripFlags};
Expand Down
4 changes: 2 additions & 2 deletions crates/re_renderer_examples/depth_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl RenderDepthClouds {
);

let command_buffer = view_builder
.queue_draw(GenericSkyboxDrawData::new(re_ctx))
.queue_draw(GenericSkyboxDrawData::new(re_ctx, Default::default()))
.queue_draw(point_cloud_draw_data)
.queue_draw(frame_draw_data)
.queue_draw(image_draw_data)
Expand Down Expand Up @@ -208,7 +208,7 @@ impl RenderDepthClouds {
);

let command_buffer = view_builder
.queue_draw(GenericSkyboxDrawData::new(re_ctx))
.queue_draw(GenericSkyboxDrawData::new(re_ctx, Default::default()))
.queue_draw(depth_cloud_draw_data)
.queue_draw(frame_draw_data)
.queue_draw(image_draw_data)
Expand Down
2 changes: 1 addition & 1 deletion crates/re_renderer_examples/multiview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ impl Example for Multiview {
IsoTransform::look_at_rh(self.camera_position, Vec3::ZERO, Vec3::Y).unwrap();

let triangle = TestTriangleDrawData::new(re_ctx);
let skybox = GenericSkyboxDrawData::new(re_ctx);
let skybox = GenericSkyboxDrawData::new(re_ctx, Default::default());
let lines = build_lines(re_ctx, seconds_since_startup);

let mut builder = PointCloudBuilder::new(re_ctx);
Expand Down
5 changes: 4 additions & 1 deletion crates/re_renderer_examples/outlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ impl framework::Example for Outlines {
})
.collect_vec();

view_builder.queue_draw(re_renderer::renderer::GenericSkyboxDrawData::new(re_ctx));
view_builder.queue_draw(re_renderer::renderer::GenericSkyboxDrawData::new(
re_ctx,
Default::default(),
));
view_builder
.queue_draw(re_renderer::renderer::MeshDrawData::new(re_ctx, &instances).unwrap());

Expand Down
7 changes: 4 additions & 3 deletions crates/re_renderer_examples/picking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,13 @@ impl framework::Example for Picking {
})
.collect_vec();

view_builder.queue_draw(re_renderer::renderer::GenericSkyboxDrawData::new(re_ctx));
view_builder.queue_draw(re_renderer::renderer::GenericSkyboxDrawData::new(
re_ctx,
Default::default(),
));
view_builder
.queue_draw(re_renderer::renderer::MeshDrawData::new(re_ctx, &instances).unwrap());

view_builder.queue_draw(re_renderer::renderer::GenericSkyboxDrawData::new(re_ctx));

let command_buffer = view_builder
.draw(re_ctx, re_renderer::Rgba::TRANSPARENT)
.unwrap();
Expand Down
10 changes: 8 additions & 2 deletions crates/re_space_view_spatial/src/space_view_2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,17 @@ impl SpaceViewClass for SpatialSpaceView2D {
ctx: &re_viewer_context::ViewerContext<'_>,
ui: &mut egui::Ui,
state: &mut Self::State,
space_origin: &EntityPath,
_space_origin: &EntityPath,
_space_view_id: SpaceViewId,
_root_entity_properties: &mut EntityProperties,
) {
state.selection_ui(ctx, ui, space_origin, SpatialSpaceViewKind::TwoD);
ctx.re_ui
.selection_grid(ui, "spatial_settings_ui")
.show(ui, |ui| {
state.default_size_ui(ctx, ui);
state.bounding_box_ui(ctx, ui, SpatialSpaceViewKind::TwoD);
ui.end_row();
});
}

fn ui(
Expand Down
Loading

0 comments on commit 7a6efff

Please sign in to comment.