Skip to content

Commit

Permalink
yet another workaround for https://github.com/gfx-rs/naga/issues/1743
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed May 3, 2023
1 parent f92a10e commit ec0a980
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
14 changes: 14 additions & 0 deletions crates/re_renderer/shader/point_cloud.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ fn vs_main(@builtin(vertex_index) vertex_idx: u32) -> VertexOut {
return out;
}

// TODO(andreas): move this to sphere_quad.wgsl once https://github.com/gfx-rs/naga/issues/1743 is resolved
// point_cloud.rs has a specific workaround in place so we don't need to split vertex/fragment shader here
//
/// Computes coverage of a 2D sphere placed at `circle_center` in the fragment shader using the currently set camera.
///
/// 2D primitives are always facing the camera - the difference to sphere_quad_coverage is that
/// perspective projection is not taken into account.
fn circle_quad_coverage(world_position: Vec3, radius: f32, circle_center: Vec3) -> f32 {
let to_center = circle_center - world_position;
let distance = length(to_center);
let distance_pixel_difference = fwidth(distance);
return smoothstep(radius + distance_pixel_difference, radius - distance_pixel_difference, distance);
}

fn coverage(world_position: Vec3, radius: f32, point_center: Vec3) -> f32 {
if is_camera_orthographic() || has_any_flag(batch.flags, DRAW_AS_CIRCLES) {
return circle_quad_coverage(world_position, radius, point_center);
Expand Down
11 changes: 0 additions & 11 deletions crates/re_renderer/shader/utils/sphere_quad.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,3 @@ fn sphere_quad_coverage(world_position: Vec3, radius: f32, sphere_center: Vec3)
// Note that we have signed distances to the sphere surface.
return saturate(0.5 - distance_to_surface_in_pixels);
}

/// Computes coverage of a 2D sphere placed at `circle_center` in the fragment shader using the currently set camera.
///
/// 2D primitives are always facing the camera - the difference to sphere_quad_coverage is that
/// perspective projection is not taken into account.
fn circle_quad_coverage(world_position: Vec3, radius: f32, circle_center: Vec3) -> f32 {
let to_center = circle_center - world_position;
let distance = length(to_center);
let distance_pixel_difference = fwidth(distance);
return smoothstep(radius + distance_pixel_difference, radius - distance_pixel_difference, distance);
}
21 changes: 15 additions & 6 deletions crates/re_renderer/src/renderer/point_cloud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,17 +624,26 @@ impl Renderer for PointCloudRenderer {
&pools.bind_group_layouts,
);

let shader_module = pools.shader_modules.get_or_create(
device,
resolver,
&include_shader_module!("../../shader/point_cloud.wgsl"),
);
let shader_module_desc = include_shader_module!("../../shader/point_cloud.wgsl");
let shader_module =
pools
.shader_modules
.get_or_create(device, resolver, &shader_module_desc);

// HACK/WORKAROUND for https://github.com/gfx-rs/naga/issues/1743
let mut shader_module_desc_vertex = shader_module_desc.clone();
shader_module_desc_vertex.extra_workaround_replacements =
vec![("fwidth(".to_owned(), "f32(".to_owned())];
let shader_module_vertex =
pools
.shader_modules
.get_or_create(device, resolver, &shader_module_desc_vertex);

let render_pipeline_desc_color = RenderPipelineDesc {
label: "PointCloudRenderer::render_pipeline_color".into(),
pipeline_layout,
vertex_entrypoint: "vs_main".into(),
vertex_handle: shader_module,
vertex_handle: shader_module_vertex,
fragment_entrypoint: "fs_main".into(),
fragment_handle: shader_module,
vertex_buffers: smallvec![],
Expand Down
10 changes: 9 additions & 1 deletion crates/re_renderer/src/wgpu_resources/shader_module_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ macro_rules! include_shader_module {
$crate::wgpu_resources::ShaderModuleDesc {
label: $crate::DebugLabel::from(stringify!($path).strip_prefix("../../shader/")),
source: $crate::include_file!($path),
extra_workaround_replacements: Vec::new(),
}
}};
}
Expand All @@ -33,6 +34,9 @@ pub struct ShaderModuleDesc {

/// Path to the source code of this shader module.
pub source: PathBuf,

/// Additional text replacement workarounds that may be added on top of globally known workarounds.
pub extra_workaround_replacements: Vec<(String, String)>,
}

impl PartialEq for ShaderModuleDesc {
Expand All @@ -46,6 +50,7 @@ impl Hash for ShaderModuleDesc {
// NOTE: for a shader, the only thing that should matter is the source
// code since we can have many entrypoints referring to the same file!
self.source.hash(state);
self.extra_workaround_replacements.hash(state);
}
}

Expand All @@ -62,7 +67,10 @@ impl ShaderModuleDesc {
.map_err(|err| re_log::error!(err=%re_error::format(err)))
.unwrap_or_default();

for (from, to) in shader_text_workaround_replacements {
for (from, to) in shader_text_workaround_replacements
.iter()
.chain(self.extra_workaround_replacements.iter())
{
source_interpolated.contents = source_interpolated.contents.replace(from, to);
}

Expand Down
1 change: 1 addition & 0 deletions crates/re_web_viewer_server/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl<'a> Packages<'a> {
// account for locally patched dependencies.
rerun_if_changed(path.join("Cargo.toml").as_ref());
rerun_if_changed(path.join("**/*.rs").as_ref());
rerun_if_changed(path.join("**/*.wgsl").as_ref());
}

// Track all direct and indirect dependencies of that root package
Expand Down

0 comments on commit ec0a980

Please sign in to comment.