Skip to content

Commit

Permalink
Apply scale from obj->world transform to radii
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed Nov 10, 2023
1 parent a4cf644 commit 74d5a3f
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 18 deletions.
8 changes: 6 additions & 2 deletions crates/re_renderer/shader/depth_cloud.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,12 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {

if 0.0 < point_data.unresolved_radius {
// Span quad
let quad = sphere_or_circle_quad_span(vertex_idx, point_data.pos_in_world, point_data.unresolved_radius,
depth_cloud_info.radius_boost_in_ui_points, false);
let camera_distance = distance(frame.camera_position, point_data.pos_in_world);
let world_scale_factor = average_scale_from_transform(depth_cloud_info.world_from_rdf); // TODO(andreas): somewhat costly, should precompute this
let world_radius = unresolved_size_to_world(point_data.unresolved_radius, camera_distance,
frame.auto_size_points, world_scale_factor) +
world_size_from_point_size(depth_cloud_info.radius_boost_in_ui_points, camera_distance);
let quad = sphere_or_circle_quad_span(vertex_idx, point_data.pos_in_world, world_radius, false);
out.pos_in_clip = frame.projection_from_world * Vec4(quad.pos_in_world, 1.0);
out.pos_in_world = quad.pos_in_world;
out.point_radius = quad.point_resolved_radius;
Expand Down
3 changes: 2 additions & 1 deletion crates/re_renderer/shader/lines.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
camera_ray = camera_ray_to_world_pos_perspective(center_position);
}
let camera_distance = distance(camera_ray.origin, center_position);
var strip_radius = unresolved_size_to_world(strip_data.unresolved_radius, camera_distance, frame.auto_size_lines);
let world_scale_factor = average_scale_from_transform(batch.world_from_obj); // TODO(andreas): somewhat costly, should precompute this
var strip_radius = unresolved_size_to_world(strip_data.unresolved_radius, camera_distance, frame.auto_size_lines, world_scale_factor);

// If the triangle cap is longer than the quad would be otherwise, we need to stunt it, otherwise we'd get artifacts.
var triangle_cap_length = batch.triangle_cap_length_factor * strip_radius;
Expand Down
9 changes: 7 additions & 2 deletions crates/re_renderer/shader/point_cloud.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,13 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
let point_data = read_data(quad_idx);

// Span quad
let quad = sphere_or_circle_quad_span(vertex_idx, point_data.pos, point_data.unresolved_radius,
draw_data.radius_boost_in_ui_points, has_any_flag(batch.flags, FLAG_DRAW_AS_CIRCLES));
let camera_distance = distance(frame.camera_position, point_data.pos);
let world_scale_factor = average_scale_from_transform(batch.world_from_obj); // TODO(andreas): somewhat costly, should precompute this
let world_radius = unresolved_size_to_world(point_data.unresolved_radius, camera_distance,
frame.auto_size_points, world_scale_factor) +
world_size_from_point_size(draw_data.radius_boost_in_ui_points, camera_distance);
let quad = sphere_or_circle_quad_span(vertex_idx, point_data.pos, world_radius,
has_any_flag(batch.flags, FLAG_DRAW_AS_CIRCLES));

// Output, transform to projection space and done.
var out: VertexOut;
Expand Down
16 changes: 14 additions & 2 deletions crates/re_renderer/shader/utils/size.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ fn world_size_from_point_size(size_in_points: f32, camera_distance: f32) -> f32
return approx_pixel_world_size_at(camera_distance) * pixel_size;
}

fn unresolved_size_to_world(_unresolved_size: f32, camera_distance: f32, auto_size: f32) -> f32 {
// Resolves a size (see size.rs!) to a world scale size.
//
// world_size_scale:
// Scale factor that is applied iff the size is a world size.
// This is usually part of your object->world transform.
fn unresolved_size_to_world(_unresolved_size: f32, camera_distance: f32, auto_size: f32, world_size_scale: f32) -> f32 {
// Resolve auto size.
var unresolved_size: f32;
if _unresolved_size >= f32max {
Expand All @@ -23,9 +28,16 @@ fn unresolved_size_to_world(_unresolved_size: f32, camera_distance: f32, auto_si

// Is it a world size?
if unresolved_size > 0.0 {
return unresolved_size;
return unresolved_size * world_size_scale;
}

// Negative size indicates size in points.
return world_size_from_point_size(-unresolved_size, camera_distance);
}

// Determines the scale factor of a matrix
// This quite expensive, you may want to precompute this.
fn average_scale_from_transform(transform: mat4x4f) -> f32 {
let scale = vec3f(length(transform[0]), length(transform[1]), length(transform[2]));
return pow(scale.x * scale.y * scale.z, 0.3333);
}
17 changes: 6 additions & 11 deletions crates/re_renderer/shader/utils/sphere_quad.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,7 @@ struct SphereQuadData {
/// Span a quad onto which circles or perspective correct spheres can be drawn.
///
/// Note that in orthographic mode, spheres are always circles.
fn sphere_or_circle_quad_span(vertex_idx: u32, point_pos: Vec3, point_unresolved_radius: f32,
radius_boost_in_ui_points: f32, force_circle: bool) -> SphereQuadData {
// Resolve radius to a world size. We need the camera distance for this, which is useful later on.
let to_camera = frame.camera_position - point_pos;
let camera_distance = length(to_camera);
let radius = unresolved_size_to_world(point_unresolved_radius, camera_distance, frame.auto_size_points) +
world_size_from_point_size(radius_boost_in_ui_points, camera_distance);

fn sphere_or_circle_quad_span(vertex_idx: u32, point_pos: Vec3, world_radius: f32, force_circle: bool) -> SphereQuadData {
// Basic properties of the vertex we're at.
let local_idx = vertex_idx % 6u;
let top_bottom = f32(local_idx <= 1u || local_idx == 5u) * 2.0 - 1.0; // 1 for a top vertex, -1 for a bottom vertex.
Expand All @@ -85,12 +78,14 @@ fn sphere_or_circle_quad_span(vertex_idx: u32, point_pos: Vec3, point_unresolved
// Span quad
var pos: Vec3;
if is_camera_orthographic() || force_circle {
pos = circle_quad(point_pos, radius, top_bottom, left_right);
pos = circle_quad(point_pos, world_radius, top_bottom, left_right);
} else {
pos = sphere_quad(point_pos, radius, top_bottom, left_right, to_camera, camera_distance);
let to_camera = frame.camera_position - point_pos;
let camera_distance = length(to_camera);
pos = sphere_quad(point_pos, world_radius, top_bottom, left_right, to_camera, camera_distance);
}

return SphereQuadData(pos, radius);
return SphereQuadData(pos, world_radius);
}

/// Computes coverage of a 3D sphere placed at `sphere_center` in the fragment shader using the currently set camera.
Expand Down

0 comments on commit 74d5a3f

Please sign in to comment.