-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Prevent DoF effect disappearing at small focus_distances
#21816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
max(focus - f, EPSILON) to ensure the denominator is alwaysfocus_distances
|
Seems the CI failed because the heapless crate update caused Bevy to use a deprecated method. May need another PR to fix this issue. |
| @group(1) @binding(1) var color_texture_sampler: sampler; | ||
|
|
||
| // used to ensure `depth * (focus - f)` is always a positive number, | ||
| const EPSILON: f32 = 1.19209290e-07; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use f32::EPSILON, no need to define a custom constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using f32::EPSILON in WGSL, but it seems this constant isn't provided by the language. So I just copied the value from Rust's standard library and defined a custom constant in my WGSL code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely forgot this was wgsl and not rust. Ignore that 😅
| // | ||
| // [1]: https://en.wikipedia.org/wiki/Circle_of_confusion#Determining_a_circle_of_confusion_diameter_from_the_object_field | ||
| let candidate_coc = scale * abs(depth - focus) / (depth * (focus - f)); | ||
| let candidate_coc = scale * abs(depth - focus) / (depth * max(focus - f, EPSILON)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| let candidate_coc = scale * abs(depth - focus) / (depth * max(focus - f, EPSILON)); | |
| let candidate_coc = scale * abs(depth - focus) / (depth * max(focus - f, f32::EPSILON)); |
Objective
depth_of_fieldexample, settingfocal_distanceto a small value (<= 0.02) causes the DoF effect to disappear unexpectedly.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.
Testing