Skip to content

Commit

Permalink
Proper defensive MIS
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Sep 18, 2024
1 parent ceb233c commit 8f153f2
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 5 deletions.
3 changes: 3 additions & 0 deletions blade-helpers/src/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ impl ExposeHud for blade_render::RayConfig {
.logarithmic(true),
);
ui.checkbox(&mut self.pairwise_mis, "Pairwise MIS");
ui.add(
egui::widgets::Slider::new(&mut self.defensive_mis, 0.0..=1.0).text("Defensive MIS"),
);
}
}

Expand Down
14 changes: 10 additions & 4 deletions blade-render/code/ray-trace.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ struct MainParams {
spatial_min_distance: i32,
t_start: f32,
use_pairwise_mis: u32,
defensive_mis: f32,
use_motion_vectors: u32,
temporal_accumulation_weight: f32,
pad: f32,
grid_scale: vec2<u32>,
}

Expand Down Expand Up @@ -424,15 +426,18 @@ fn resample(
if (parameters.use_pairwise_mis != 0u) {
let canonical = base.canonical;
let neighbor_history = min(neighbor.confidence, max_confidence);
let mis_scale = 1.0 / (base.accepted_count + parameters.defensive_mis);
{ // scoping this to hint the register allocation
let t_canonical_at_neighbor = estimate_target_score_with_occlusion(
other.surface, other.world_pos, canonical.selected_light_index, canonical.selected_uv, other_acs);
rr.mis_canonical = ratio(canonical.selected_target_score, t_canonical_at_neighbor.score) / base.accepted_count;
let r_canonical = ratio(canonical.history * canonical.selected_target_score / base.accepted_count, neighbor_history * t_canonical_at_neighbor.score);
rr.mis_canonical = mis_scale * (parameters.defensive_mis / base.accepted_count + r_canonical);
}

let t_neighbor_at_canonical = estimate_target_score_with_occlusion(
base.surface, base.world_pos, neighbor.light_index, neighbor.light_uv, acc_struct);
rr.mis_sample = ratio(neighbor.target_score, t_neighbor_at_canonical.score) / base.accepted_count;
let r_neighbor = ratio(neighbor_history * neighbor.target_score, canonical.history * t_neighbor_at_canonical.score / base.accepted_count);
rr.mis_sample = mis_scale * r_neighbor;

src.history = neighbor_history;
src.selected_light_index = neighbor.light_index;
Expand Down Expand Up @@ -523,15 +528,16 @@ fn resample_temporal(
let prev_world_pos = prev_camera.position + tr.surface.depth * prev_dir;
let other = PixelCache(tr.surface, tr.reservoir, prev_world_pos);
let rr = resample(&reservoir, &color_and_weight, base, other, prev_acc_struct, parameters.temporal_tap_confidence);
let mis_canonical = rr.mis_canonical;

if (WRITE_DEBUG_IMAGE && debug.view_mode == DebugMode_TemporalMatch) {
textureStore(out_debug, cur_pixel, vec4<f32>(1.0));
}
if (WRITE_DEBUG_IMAGE && debug.view_mode == DebugMode_TemporalMisCanonical) {
textureStore(out_debug, cur_pixel, vec4<f32>(rr.mis_canonical));
textureStore(out_debug, cur_pixel, vec4<f32>(mis_canonical));
}

return finalize_resampling(&reservoir, &color_and_weight, base, rr.mis_canonical);
return finalize_resampling(&reservoir, &color_and_weight, base, mis_canonical);
}

fn resample_spatial(
Expand Down
5 changes: 5 additions & 0 deletions blade-render/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ pub struct RayConfig {
/// See "9.1 pairwise mis for robust reservoir reuse"
/// "Correlations and Reuse for Fast and Accurate Physically Based Light Transport"
pub pairwise_mis: bool,
pub defensive_mis: f32,
}

#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -374,8 +375,10 @@ struct MainParams {
spatial_min_distance: u32,
t_start: f32,
use_pairwise_mis: u32,
defensive_mis: f32,
use_motion_vectors: u32,
temporal_accumulation_weight: f32,
pad: u32,
grid_scale: [u32; 2],
}

Expand Down Expand Up @@ -1098,12 +1101,14 @@ impl Renderer {
spatial_min_distance: ray_config.spatial_min_distance,
t_start: ray_config.t_start,
use_pairwise_mis: ray_config.pairwise_mis as u32,
defensive_mis: ray_config.defensive_mis,
use_motion_vectors: (self.frame_scene_built == self.frame_index) as u32,
temporal_accumulation_weight: if denoiser_config.enabled {
denoiser_config.temporal_weight
} else {
1.0
},
pad: 0,
grid_scale,
},
acc_struct: self.acceleration_structure,
Expand Down
1 change: 1 addition & 0 deletions examples/scene/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ impl Example {
group_mixer: 10,
t_start: 0.1,
pairwise_mis: true,
defensive_mis: 0.0,
},
denoiser_config: blade_render::DenoiserConfig {
enabled: true,
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,11 +487,12 @@ impl Engine {
temporal_tap: true,
temporal_confidence: 10.0,
spatial_taps: 1,
spatial_confidence: 5.0,
spatial_confidence: 10.0,
spatial_min_distance: 2,
group_mixer: 10,
t_start: 0.01,
pairwise_mis: true,
defensive_mis: 0.1,
},
denoiser_config: blade_render::DenoiserConfig {
enabled: true,
Expand Down

0 comments on commit 8f153f2

Please sign in to comment.