Skip to content

Commit a32ffae

Browse files
authored
Solari fixes (#21747)
* Fix overflow/nans in BRDF evaluation * Reduce jacobian rejection threshold to prevent light leaks (more aggressive cutoff now)
1 parent 2eec49d commit a32ffae

File tree

4 files changed

+11
-7
lines changed

4 files changed

+11
-7
lines changed

crates/bevy_solari/src/pathtracer/pathtracer.wgsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn importance_sample_next_bounce(wo: vec3<f32>, ray_hit: ResolvedRayHitFull, rng
104104
if is_perfectly_specular {
105105
return NextBounce(reflect(-wo, ray_hit.world_normal), 1.0, true);
106106
}
107-
let diffuse_weight = mix(mix(0.4f, 0.9f, ray_hit.material.perceptual_roughness), 0.f, ray_hit.material.metallic);
107+
let diffuse_weight = mix(mix(0.4, 0.9, ray_hit.material.perceptual_roughness), 0.0, ray_hit.material.metallic);
108108
let specular_weight = 1.0 - diffuse_weight;
109109

110110
let TBN = calculate_tbn_mikktspace(ray_hit.world_normal, ray_hit.world_tangent);
@@ -133,7 +133,7 @@ fn importance_sample_next_bounce(wo: vec3<f32>, ray_hit: ResolvedRayHitFull, rng
133133
}
134134

135135
fn brdf_pdf(wo: vec3<f32>, wi: vec3<f32>, ray_hit: ResolvedRayHitFull) -> f32 {
136-
let diffuse_weight = mix(mix(0.4f, 0.9f, ray_hit.material.roughness), 0.f, ray_hit.material.metallic);
136+
let diffuse_weight = mix(mix(0.4, 0.9, ray_hit.material.roughness), 0.0, ray_hit.material.metallic);
137137
let specular_weight = 1.0 - diffuse_weight;
138138

139139
let TBN = calculate_tbn_mikktspace(ray_hit.world_normal, ray_hit.world_tangent);

crates/bevy_solari/src/realtime/gbuffer_utils.wgsl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ fn gpixel_resolve(gpixel: vec4<u32>, depth: f32, pixel_id: vec2<u32>, view_size:
1818

1919
let base_rough = unpack4x8unorm(gpixel.r);
2020
let base_color = pow(base_rough.rgb, vec3(2.2));
21-
let perceptual_roughness = base_rough.a;
22-
let roughness = clamp(perceptual_roughness * perceptual_roughness, 0.001, 1.0);
21+
// Clamp roughness to prevent NaNs
22+
let perceptual_roughness = clamp(base_rough.a, 0.0316227766, 1.0); // Clamp roughness to 0.001
23+
let roughness = perceptual_roughness * perceptual_roughness;
2324
let props = unpack4x8unorm(gpixel.b);
2425
let reflectance = vec3(props.r);
25-
let metallic = props.g;
26+
let metallic = saturate(props.g); // TODO: Not sure why saturate is needed here to prevent NaNs
2627
let emissive = rgb9e5_to_vec3_(gpixel.g);
2728
let material = ResolvedMaterial(base_color, emissive, reflectance, perceptual_roughness, roughness, metallic);
2829

crates/bevy_solari/src/realtime/restir_gi.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ fn merge_reservoirs(
274274
);
275275

276276
// Don't merge samples with huge jacobians, as it explodes the variance
277-
if canonical_target_function_other_sample_jacobian > 2.0 {
277+
if canonical_target_function_other_sample_jacobian > 1.2 {
278278
return ReservoirMergeResult(canonical_reservoir, canonical_sample_radiance);
279279
}
280280

crates/bevy_solari/src/scene/raytracing_scene_bindings.wgsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,10 @@ fn resolve_material(material: Material, uv: vec2<f32>) -> ResolvedMaterial {
142142
m.perceptual_roughness *= metallic_roughness.g;
143143
m.metallic *= metallic_roughness.b;
144144
}
145-
m.roughness = clamp(m.perceptual_roughness * m.perceptual_roughness, 0.001, 1.0);
145+
146+
// Clamp roughness to prevent NaNs
147+
m.perceptual_roughness = clamp(m.perceptual_roughness, 0.0316227766, 1.0); // Clamp roughness to 0.001
148+
m.roughness = m.perceptual_roughness * m.perceptual_roughness;
146149

147150
return m;
148151
}

0 commit comments

Comments
 (0)