Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use GPU picking for line(like) primitives, fix interactive flags #1829

Merged
merged 16 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/re_renderer/examples/2d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl framework::Example for Render2D {
splits[0].resolution_in_pixel[1] as f32,
);

let mut line_strip_builder = LineStripSeriesBuilder::<()>::new(re_ctx);
let mut line_strip_builder = LineStripSeriesBuilder::new(re_ctx);

// Blue rect outline around the bottom right quarter.
{
Expand Down Expand Up @@ -182,7 +182,7 @@ impl framework::Example for Render2D {
}
}

let line_strip_draw_data = line_strip_builder.to_draw_data(re_ctx);
let line_strip_draw_data = line_strip_builder.to_draw_data(re_ctx).unwrap();
let point_draw_data = point_cloud_builder.to_draw_data(re_ctx).unwrap();

let image_scale = 4.0;
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 @@ -312,7 +312,7 @@ impl framework::Example for RenderDepthClouds {
let world_from_model = rotation * translation_center * scale;

let frame_draw_data = {
let mut builder = LineStripSeriesBuilder::<()>::new(re_ctx);
let mut builder = LineStripSeriesBuilder::new(re_ctx);
{
let mut line_batch = builder.batch("frame").world_from_obj(world_from_model);
line_batch.add_box_outline(glam::Affine3A::from_scale_rotation_translation(
Expand All @@ -321,7 +321,7 @@ impl framework::Example for RenderDepthClouds {
glam::Vec3::ONE * 0.5,
));
}
builder.to_draw_data(re_ctx)
builder.to_draw_data(re_ctx).unwrap()
};

let image_draw_data = RectangleDrawData::new(
Expand Down
4 changes: 2 additions & 2 deletions crates/re_renderer/examples/multiview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fn build_lines(re_ctx: &mut RenderContext, seconds_since_startup: f32) -> LineDr
// Calculate some points that look nice for an animated line.
let lorenz_points = lorenz_points(seconds_since_startup);

let mut builder = LineStripSeriesBuilder::<()>::new(re_ctx);
let mut builder = LineStripSeriesBuilder::new(re_ctx);
{
let mut batch = builder.batch("lines without transform");

Expand Down Expand Up @@ -125,7 +125,7 @@ fn build_lines(re_ctx: &mut RenderContext, seconds_since_startup: f32) -> LineDr
.radius(Size::new_scene(0.1))
.flags(LineStripFlags::CAP_END_TRIANGLE);

builder.to_draw_data(re_ctx)
builder.to_draw_data(re_ctx).unwrap()
}

enum CameraControl {
Expand Down
22 changes: 16 additions & 6 deletions crates/re_renderer/shader/lines.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
var line_strip_texture: texture_2d<f32>;
@group(1) @binding(1)
var position_data_texture: texture_2d<u32>;
@group(1) @binding(2)
var picking_instance_id_texture: texture_2d<u32>;

struct DrawDataUniformBuffer {
radius_boost_in_ui_points: f32,
Expand All @@ -19,21 +21,22 @@ struct DrawDataUniformBuffer {
// if we wouldn't add padding here, which isn't available on WebGL.
_padding: Vec4,
};
@group(1) @binding(2)
@group(1) @binding(3)
var<uniform> draw_data: DrawDataUniformBuffer;

struct BatchUniformBuffer {
world_from_obj: Mat4,
outline_mask_ids: UVec2,
picking_layer_object_id: UVec2,
};
@group(2) @binding(0)
var<uniform> batch: BatchUniformBuffer;


// textureLoad needs i32 right now, so we use that with all sizes & indices to avoid casts
// https://github.com/gfx-rs/naga/issues/1997
const LINESTRIP_TEXTURE_SIZE: i32 = 512;
const POSITION_DATA_TEXTURE_SIZE: i32 = 256;
const POSITION_TEXTURE_SIZE: i32 = 512;
const LINE_STRIP_TEXTURE_SIZE: i32 = 256;

// Flags
// See lines.rs#LineStripFlags
Expand Down Expand Up @@ -69,20 +72,25 @@ struct VertexOut {

@location(5) @interpolate(flat)
fragment_flags: u32,

@location(6) @interpolate(flat)
picking_instance_id: UVec2,
};

struct LineStripData {
color: Vec4,
unresolved_radius: f32,
stippling: f32,
flags: u32,
picking_instance_id: UVec2,
}

// Read and unpack line strip data at a given location
fn read_strip_data(idx: u32) -> LineStripData {
// can be u32 once https://github.com/gfx-rs/naga/issues/1997 is solved
let idx = i32(idx);
var raw_data = textureLoad(position_data_texture, IVec2(idx % POSITION_DATA_TEXTURE_SIZE, idx / POSITION_DATA_TEXTURE_SIZE), 0).xy;
let coord = IVec2(idx % LINE_STRIP_TEXTURE_SIZE, idx / LINE_STRIP_TEXTURE_SIZE);
var raw_data = textureLoad(position_data_texture, coord, 0).xy;

var data: LineStripData;
data.color = linear_from_srgba(unpack4x8unorm_workaround(raw_data.x));
Expand All @@ -91,6 +99,7 @@ fn read_strip_data(idx: u32) -> LineStripData {
data.unresolved_radius = unpack2x16float(raw_data.y).y;
data.flags = ((raw_data.y >> 8u) & 0xFFu);
data.stippling = f32((raw_data.y >> 16u) & 0xFFu) * (1.0 / 255.0);
data.picking_instance_id = textureLoad(picking_instance_id_texture, coord, 0).rg;
return data;
}

Expand All @@ -103,7 +112,7 @@ struct PositionData {
fn read_position_data(idx: u32) -> PositionData {
// can be u32 once https://github.com/gfx-rs/naga/issues/1997 is solved
let idx = i32(idx);
var raw_data = textureLoad(line_strip_texture, IVec2(idx % LINESTRIP_TEXTURE_SIZE, idx / LINESTRIP_TEXTURE_SIZE), 0);
var raw_data = textureLoad(line_strip_texture, IVec2(idx % POSITION_TEXTURE_SIZE, idx / POSITION_TEXTURE_SIZE), 0);

var data: PositionData;
let pos_4d = batch.world_from_obj * Vec4(raw_data.xyz, 1.0);
Expand Down Expand Up @@ -262,6 +271,7 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
out.active_radius = active_radius;
out.fragment_flags = strip_data.flags &
(NO_COLOR_GRADIENT | (u32(is_cap_triangle) * select(CAP_START_ROUND, CAP_END_ROUND, is_right_triangle)));
out.picking_instance_id = strip_data.picking_instance_id;

return out;
}
Expand Down Expand Up @@ -305,7 +315,7 @@ fn fs_main_picking_layer(in: VertexOut) -> @location(0) UVec4 {
if coverage < 0.5 {
discard;
}
return UVec4(0u, 0u, 0u, 0u); // TODO(andreas): Implement picking layer id pass-through.
return UVec4(batch.picking_layer_object_id, in.picking_instance_id);
}

@fragment
Expand Down
Loading