Procedural atmospheric scattering
Implement procedural atmospheric scattering from Sebastien Hillaire's 2020 paper. This approach should scale well even down to mobile hardware, and is physically accurate.
TODO
~~- implement multiscattering (followup?)~~ (in progress, just bugfixes left)~~ ~~- handle scene units better~~ ~~- fix over-exposure~~ ~~- check physical correctness~~ ~~- check that coordinates are correct (lat-long -> ray direction specifically, and that signs for depth + view dir are correct)~~
- integrate with pcwalton's volumetrics code (could have volumetric shadows with accurate sky color!!) (definitely in a followup) ~~- draw sun disks (get radius from shadow softness value?)~~
- handle hdr/non-hdr view texture
- handle MSAA
- set camera depth texture usages automatically
- fix sun disk aliasing
Showcase
Check the example in examples/3d/atmosphere.rs.
The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.
Wow, this is very impressive! I'll review.
Considering the Atmosphere takes parameters about the inner and outer radius of the atmosphere, maybe it would make sense if that component was on another entity? That would allow you to compute the camera's view within (or outside) the atmosphere based on the position of the atmosphere and the camera using their GlobalTransforms. Excited to see this implemented!
The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.
The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.
Would you like reviews/feedback on this at this stage or is it too early?
Would you like reviews/feedback on this at this stage or is it too early?
The structure of everything is pretty much final so feedback on that would be nice :). At this stage I'm mainly trying to make everything physically correct, so things will change there but if you see something I'm clearly doing wrong lmk
Considering the
Atmospheretakes parameters about the inner and outer radius of the atmosphere, maybe it would make sense if that component was an another entity? That would allow you to compute the camera's view within (or outside) the atmosphere based on the position of the atmosphere and the camera using theirGlobalTransforms. Excited to see this implemented!
Some of the main assumptions made are that the center of the planet is at position (view.x, -bottom_radius, view.z) and that the camera never leaves the atmosphere. So this implementation doesn't support worlds that are actually spherical, or space scenes where the camera can view the atmosphere from above. In the future once this gets integrated with pcwalton's raytracing code, it might be worth removing these restrictions. In that case I'd agree that the atmosphere/planet should be its own entity
The generated examples/README.md is out of sync with the example metadata in Cargo.toml or the example readme template. Please run cargo run -p build-templated-pages -- update examples to update it, and commit the file change.
You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features to update it, and commit the file change.
Some of the main assumptions made
I thought the Hillaire paper explicitly allows for space views of the atmosphere? Anyway, I totally understand if it is out of scope. Thanks for working on this!
Some of the main assumptions made
I thought the Hillaire paper explicitly allows for space views of the atmosphere? Anyway, I totally understand if it is out of scope. Thanks for working on this!
It does, but the higher altitude the camera is the worse precision the sky-view and aerial-view LUTs are, even within the atmosphere. The paper recommends switching to per-pixel raytracing for high-altitude or space shots, which is where I'd want to integrate pcwalton's volumetrics code. I'd prefer that in a followup though :)
Gonna put this up for review, I know the sunrise/set colors aren't perfectly accurate, but I've been unable to fix it. I'd be perfectly fine merging this as an experimental module, considering I still need to merge it and pcwalton's volumetrics stuff into a single module as a followup. I'm just really ready to be done with this pr lmao.
You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features to update it, and commit the file change.
FYI turning on Msaa causes the app to crash. Should probably defend against this. Some render features see MSAA turned on, warn, and don't run anything in the plugin.
FYI turning on
Msaacauses the app to crash. Should probably defend against this. Some render features see MSAA turned on, warn, and don't run anything in the plugin.
this is a bug then, msaa should be compatible. will fix 👍
You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features to update it, and commit the file change.
FYI turning on
Msaacauses the app to crash. Should probably defend against this. Some render features see MSAA turned on, warn, and don't run anything in the plugin.
I noted that, in my test environment Msaa::Sample4 works fine with the atmosphere shader as well, while Msaa::Sample8 crashes which is expected due to limitations in the device. So this is no cause for concern.
For reviewers: Can we get an updated list of known problems posted in the comments? Is this PR still in draft or ready for reviews and merging?
For reviewers: Can we get an updated list of known problems posted in the comments? Is this PR still in draft or ready for reviews and merging?
Only known issues:
- banding in sky view lut at high altitudes
- view space "rings" in aerial view lut when looking down from high altitude.
However, issues at high altitude/long distances are to be expected with the lut based approach. Mitigations/improvements are possible but I don't think we need to block on that.
Actually there's another: MSAAx8 for Rgba16Float on MacOS. Is a hard error fine here? It's supported for other sample counts so we shouldn't disable the plugin entirely. I'm open to input on error handling standards here.
Issues at high altitudes are fine for this PR imo, we don't need to fix that now as long as it works from the ground and reasonable heights.
Have all the exposure issues been fixed? At least manual exposures, if auto exposure needs tuning that's a separate, unrelated issue.
Does the MSAA issue only occur when rendering the atmosphere/LUTs, or does it occur when you use 8x MSAA on macOS with camera hdr=true? Imo we're fine to just let it crash. Maybe add a warning to either the atmosphere docs or MSAA docs.
Exposure/sun color should all be fully accurate now.
Where before we were using a slightly yellow sun with lux::AMBIENT_SUNLIGHT in the example, which incorrectly approximated the sun illuminance after passing through the atmosphere, now we're using a white sun with lux::RAW_SUNLIGHT = 130_000, which gets us much closer to the the look of the unreal implementation. This does result in terrain being slightly over-brightened because we don't consider transmittance in the pbr shader yet (since it affects view specialization etc), but that'll be part of the first followup .
We also fixed the issue with the sun disks not having proper bloom applied, which was happening because of mismatched units. Directional lights specify illuminance, or light falling on an area, which isn't accurate when considering light rays directly hitting the camera sensor. To correct this, we divide by the sun's solid angle in the sun disk loop.
~~I think there may be an issue with units? I ran the atmosphere example and set the camera transform to Transform::from_xyz(0.0, 10.0, 0.0).looking_to(Dir3::X, Dir3::Y) and here's what I'm seeing:~~
~~I assume the altitude is derived from the camera's height? Leaving aside the issue that this won't work for games set in space, 10 meters elevation shouldn't look like this. I'm still reading through the paper and coming to grips with the code, but I'm wondering if for example
y=1 is corresponding to "edge of the atmosphere" maybe?~~
I just found the scene_units_to_m parameter. That explains everything!
bevy_example_runner results: https://pixel-eagle.com/project/B25A040A-A980-4602-B90C-D480AB84076D?filter=PR-16314
Nothing seems super out of place
Unassigning myself as this has enough reviews already.
Agreed, merging :) Thanks!
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to https://github.com/bevyengine/bevy-website/issues/1984 if you'd like to help out.