Commit 16a6a96
Generalized atmospheric scattering media (#20838)
# Objective
Right now, only a very small set of atmospheres are possible with Bevy's
atmospheric scattering system because of the fixed set of scattering
terms available. For example, a scene set in a dry, desert environment
might want a dense low-lying layer of dust particulate separate from the
ambient dust in the atmosphere. This PR introduces a mechanism for
generalized scattering media, replacing the fixed scattering terms with
a customizable asset.
## Solution
```rust
#[derive(TypePath, Asset, Clone)]
pub struct ScatteringMedium {
pub label: Option<Cow<'static, str>>,
pub falloff_resolution: u32,
pub phase_resolution: u32,
pub terms: SmallVec<[ScatteringTerm; 1]>,
}
```
<details>
<summary>see other new types</summary>
```rust
#[derive(Default, Clone)]
pub struct ScatteringTerm {
pub absorption: Vec3,
pub scattering: Vec3,
pub falloff: Falloff,
pub phase: PhaseFunction,
}
#[derive(Default, Clone)]
pub enum Falloff {
#[default]
Linear,
Exponential {
scale: f32,
},
Tent {
center: f32,
width: f32,
},
/// A falloff function defined by a custom curve.
///
/// domain: [0, 1),
/// range: [0, 1],
Curve(Arc<dyn Curve<f32> + Send + Sync>),
}
#[derive(Clone)]
pub enum PhaseFunction {
Isotropic,
Rayleigh,
Mie {
/// domain: [-1, 1]
bias: f32,
},
/// A phase function defined by a custom curve.
///
/// domain: [-1, 1]
/// range: [0, 1]
Curve(Arc<dyn Curve<f32> + Send + Sync>),
}
```
</details>
`ScatteringMedium` contains a list of `ScatteringTerms`, which are
processed into a set of two LUTs:
- The "density LUT", a 2D `falloff_resolution x 2` LUT which contains
the medium's optical density with respect to the atmosphere's "falloff
parameter", a linear value which is 1.0 at the planet's surface and 0.0
at the edge of space. Absorption density and scattering density
correspond to the first and second rows respectively.
- The "scattering LUT", a 2D `falloff_resolution x phase_resolution` LUT
which contains the medium's scattering density multiplied by the phase
function, with the U axis corresponding to the falloff parameter and the
V axis corresponding to `neg_LdotV * 0.5 + 0.5`, where `neg_LdotV` is
the dot product of the light direction and the outgoing view vector.
## Testing
- Need to verify output, should be almost exactly the same
- exponential falloff is slightly different now, but verified new
parameters against the old in Desmos.
## TODOS:
- Docs Docs Docs
- Cleanup
- profile perf
- reduce memory usage/traffic. This approach requires a few extra
texture samples in the inner loop of each pass. Each atmosphere LUT is
still quite small, but texture samples are expensive and the new LUTs
use f32 texels currently.
## Showcase
<details>
<summary>Click to view showcase</summary>
```rust
fn init_atmosphere(mut commands: Commands, scattering_media: ResMut<Assets<ScatteringMedium>>) {
let earth_atmosphere = scattering_media.add(
ScatteringMedium::new(
256,
256,
[
// rayleigh scattering
ScatteringTerm {
absorption: Vec3::ZERO,
scattering: Vec3::new(5.802e-6, 13.558e-6, 33.100e-6),
falloff: Falloff::Exponential { scale: 12.5 },
phase: PhaseFunction::Rayleigh,
},
// mie scattering
ScatteringTerm {
absorption: Vec3::splat(3.996e-6),
scattering: Vec3::splat(0.444e-6),
falloff: Falloff::Exponential { scale: 83.5 },
phase: PhaseFunction::Mie { bias: 0.8 },
},
// ozone
ScatteringTerm {
absorption: Vec3::new(0.650e-6, 1.881e-6, 0.085e-6),
scattering: Vec3::ZERO,
falloff: Falloff::Tent {
center: 0.75,
width: 0.3,
},
phase: PhaseFunction::Isotropic,
},
],
));
commands.spawn((
Camera3d::default(),
Atmosphere {
bottom_radius: 6_360_000.0,
top_radius: 6_460_000.0,
ground_albedo: Vec3::splat(0.3),
medium: earth_atmosphere,
},
));
}
```
</details>
---------
Co-authored-by: Máté Homolya <[email protected]>1 parent d5a16b7 commit 16a6a96
File tree
18 files changed
+1078
-398
lines changed- crates/bevy_pbr/src
- atmosphere
- examples/3d
- release-content
- migration-guides
- release-notes
18 files changed
+1078
-398
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | | - | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
26 | | - | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
| |||
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
44 | | - | |
45 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
46 | 50 | | |
47 | 51 | | |
48 | 52 | | |
49 | | - | |
| 53 | + | |
50 | 54 | | |
51 | 55 | | |
52 | | - | |
| 56 | + | |
53 | 57 | | |
54 | 58 | | |
55 | 59 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
33 | | - | |
34 | 32 | | |
35 | 33 | | |
36 | 34 | | |
| |||
65 | 63 | | |
66 | 64 | | |
67 | 65 | | |
68 | | - | |
| 66 | + | |
69 | 67 | | |
70 | 68 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
88 | 93 | | |
89 | 94 | | |
90 | 95 | | |
| |||
101 | 106 | | |
102 | 107 | | |
103 | 108 | | |
104 | | - | |
| 109 | + | |
105 | 110 | | |
106 | 111 | | |
107 | 112 | | |
| |||
110 | 115 | | |
111 | 116 | | |
112 | 117 | | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
128 | 133 | | |
129 | 134 | | |
130 | 135 | | |
| |||
135 | 140 | | |
136 | 141 | | |
137 | 142 | | |
138 | | - | |
| 143 | + | |
139 | 144 | | |
140 | 145 | | |
141 | 146 | | |
| |||
246 | 251 | | |
247 | 252 | | |
248 | 253 | | |
249 | | - | |
| 254 | + | |
250 | 255 | | |
251 | 256 | | |
252 | 257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
0 commit comments