-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Tweak exponential falloff in ScatteringTerm
#21644
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
Open
ecoskey
wants to merge
1
commit into
bevyengine:main
Choose a base branch
from
ecoskey:feature/expo_falloff
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -117,23 +117,31 @@ impl ScatteringMedium { | |
| } | ||
|
|
||
| /// Returns a scattering medium representing an earthlike atmosphere. | ||
| /// | ||
| /// Uses physically-based scale heights from Earth's atmosphere, assuming | ||
| /// a 60 km atmosphere height: | ||
| /// - Rayleigh (molecular) scattering: 8 km scale height | ||
| /// - Mie (aerosol) scattering: 1.2 km scale height | ||
| pub fn earthlike(falloff_resolution: u32, phase_resolution: u32) -> Self { | ||
| Self::new( | ||
| falloff_resolution, | ||
| phase_resolution, | ||
| [ | ||
| // Rayleigh scattering Term | ||
| ScatteringTerm { | ||
| absorption: Vec3::ZERO, | ||
| scattering: Vec3::new(5.802e-6, 13.558e-6, 33.100e-6), | ||
| falloff: Falloff::Exponential { strength: 12.5 }, | ||
| falloff: Falloff::Exponential { scale: 8.0 / 60.0 }, | ||
| phase: PhaseFunction::Rayleigh, | ||
| }, | ||
| // Mie scattering Term | ||
| ScatteringTerm { | ||
| absorption: Vec3::splat(3.996e-6), | ||
| scattering: Vec3::splat(0.444e-6), | ||
| falloff: Falloff::Exponential { strength: 83.5 }, | ||
| falloff: Falloff::Exponential { scale: 1.2 / 60.0 }, | ||
| phase: PhaseFunction::Mie { asymmetry: 0.8 }, | ||
| }, | ||
| // Ozone scattering Term | ||
| ScatteringTerm { | ||
| absorption: Vec3::new(0.650e-6, 1.881e-6, 0.085e-6), | ||
| scattering: Vec3::ZERO, | ||
|
|
@@ -203,18 +211,30 @@ pub enum Falloff { | |
| /// f(p) = p | ||
| #[default] | ||
| Linear, | ||
| /// An exponential falloff function with adjustable strength. | ||
| /// An exponential falloff function parametrized by a proportional scale. | ||
| /// When paired with an absolute "falloff distance" like the distance from | ||
| /// Earth's surface to the edge of space, this is analogous to the "height | ||
| /// scale" value common in atmospheric scattering literature, though it will | ||
| /// diverge from this for large or negative `scale` values. | ||
| /// | ||
| /// f(1) = 1 | ||
| /// f(0) = 0 | ||
| /// f(p) = (e^sp - 1)/(e^s - 1) | ||
| /// f(p) = (e^((1-p)/s) - e^(1/s))/(e - e^(1/s)) | ||
| Exponential { | ||
| /// The "strength" of the exponential falloff. The higher | ||
| /// this value is, the quicker the medium's density will | ||
| /// decrease with distance. | ||
| /// The "scale" of the exponential falloff. Values closer to zero will | ||
| /// produce steeper falloff, and values farther from zero will produce | ||
| /// gentler falloff, approaching linear falloff as scale goes to `+-∞`. | ||
| /// | ||
| /// Negative values change the *concavity* of the falloff function: | ||
| /// rather than an initial narrow region of steep falloff followed by a | ||
| /// wide region of gentle falloff, there will be an initial wide region | ||
| /// of gentle falloff followed by a narrow region of steep falloff. | ||
| /// | ||
| /// domain: (-∞, ∞) | ||
| strength: f32, | ||
| /// | ||
| /// NOTE, this function is not defined when `scale == 0`. | ||
| /// In that case, it will fall back to linear falloff. | ||
| scale: f32, | ||
| }, | ||
| /// A tent-shaped falloff function, which produces a triangular | ||
| /// peak at the center and linearly falls off to either side. | ||
|
|
@@ -244,25 +264,23 @@ impl Falloff { | |
| Self::Curve(Arc::new(curve)) | ||
| } | ||
|
|
||
| fn sample(&self, falloff: f32) -> f32 { | ||
| fn sample(&self, p: f32) -> f32 { | ||
| match self { | ||
| Falloff::Linear => falloff, | ||
| Falloff::Exponential { strength } => { | ||
| // fill discontinuity at strength == 0 | ||
| if *strength == 0.0 { | ||
| falloff | ||
| Falloff::Linear => p, | ||
| Falloff::Exponential { scale } => { | ||
| // fill discontinuity at scale == 0, | ||
| // arbitrarily choose linear falloff | ||
| if *scale == 0.0 { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This discontinuity is kind of unfortunate, since it's there because of the division by |
||
| p | ||
| } else { | ||
| let scale_exp_m1 = ops::exp_m1(*strength); | ||
| let domain_offset = ops::ln(scale_exp_m1.abs()); | ||
| let range_offset = scale_exp_m1.recip(); | ||
| let eval_pos = falloff * strength - domain_offset; | ||
| scale_exp_m1.signum() * ops::exp(eval_pos) - range_offset | ||
| let s = -1.0 / scale; | ||
| let exp_p_s = ops::exp((1.0 - p) * s); | ||
| let exp_s = ops::exp(s); | ||
| (exp_p_s - exp_s) / (1.0 - exp_s) | ||
| } | ||
| } | ||
| Falloff::Tent { center, width } => { | ||
| (1.0 - (falloff - center).abs() / (0.5 * width)).max(0.0) | ||
| } | ||
| Falloff::Curve(curve) => curve.sample(falloff).unwrap_or(0.0), | ||
| Falloff::Tent { center, width } => (1.0 - (p - center).abs() / (0.5 * width)).max(0.0), | ||
| Falloff::Curve(curve) => curve.sample(p).unwrap_or(0.0), | ||
| } | ||
| } | ||
| } | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 took this directly from your pr @mate-h, but isn't this meant to be 100km?