Skip to content

Commit 2930d9f

Browse files
Prevent DoF effect disappearing at small focus_distances (bevyengine#21816)
# Objective - In the `depth_of_field` example, setting `focal_distance` to a small value (<= 0.02) causes the DoF effect to disappear unexpectedly. <img width="1936" height="1129" alt="before" src="https://github.com/user-attachments/assets/ea12016e-b9d5-4232-b8e0-b354efdecaae" /> - I believe that a small focal_distance makes `(focus - f)` zero or negative. This leads to a non-positive candidate_coc, which is then clamped to 0.0, effectively disabling the DoF effect. - Although the formula is physically accurate, we cannot assume users have a deep understanding of the depth of field effect. This will make them confused. ## Solution - Use `max(focus - f, EPSILON)` to ensure the denominator is always positive. - Now, the effect looks correct. <img width="1938" height="1135" alt="later" src="https://github.com/user-attachments/assets/4462bc78-e5d1-4d74-a9c7-d69ed111b4c6" /> ## Testing - CI ---
1 parent 0c90f04 commit 2930d9f

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

crates/bevy_post_process/src/dof/dof.wgsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ struct DualOutput {
9898
// The sampler that's used to fetch texels from the source color buffer.
9999
@group(1) @binding(1) var color_texture_sampler: sampler;
100100

101+
// used to ensure `depth * (focus - f)` is always a positive number,
102+
const EPSILON: f32 = 1.19209290e-07;
101103
// cos(-30°), used for the bokeh blur.
102104
const COS_NEG_FRAC_PI_6: f32 = 0.8660254037844387;
103105
// sin(-30°), used for the bokeh blur.
@@ -128,7 +130,7 @@ fn calculate_circle_of_confusion(in_frag_coord: vec4<f32>) -> f32 {
128130
// This is just the formula from Wikipedia [1].
129131
//
130132
// [1]: https://en.wikipedia.org/wiki/Circle_of_confusion#Determining_a_circle_of_confusion_diameter_from_the_object_field
131-
let candidate_coc = scale * abs(depth - focus) / (depth * (focus - f));
133+
let candidate_coc = scale * abs(depth - focus) / (depth * max(focus - f, EPSILON));
132134

133135
let framebuffer_size = vec2<f32>(textureDimensions(color_texture_a));
134136
return clamp(candidate_coc * framebuffer_size.y, 0.0, max_coc_diameter);

examples/3d/depth_of_field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ impl AppSettings {
243243

244244
format!(
245245
"Focal distance: {:.2} m (Press Up/Down to change)
246-
Aperture F-stops: f/{:.2} (Press Left/Right to change)
246+
Aperture F-stops: f/{:.3} (Press Left/Right to change)
247247
Sensor height: {:.2}mm
248248
Focal length: {:.2}mm
249249
Mode: {} (Press Space to change)",

0 commit comments

Comments
 (0)