WIP: Multiple atmospheres in one scene#19
Open
mate-h wants to merge 1 commit into
Open
Conversation
This was referenced Apr 2, 2026
github-merge-queue Bot
pushed a commit
to bevyengine/bevy
that referenced
this pull request
Apr 6, 2026
# Objective **Anecdotal feedback:** - no floating origin support for implementing large-scale worlds, forked Bevy's atmosphere at https://github.com/philpax/veldera/blob/main/crates/bevy_pbr_atmosphere_planet/NOTICE.md - no custom up axis support, resorted to using a custom sky shader for flight simulator with Z up coordinate system. Bevy's atmosphere appears tilted at a 90 degree angle with no way of changing it. ## Solution - Atmosphere component can be spawned stand-alone - AtmosphereSettings remains on camera - A closest-to-camera heuristic is used to pick the primary atmosphere to render. Deliberately no multi-atmosphere support to keep the scope of this PR small and self contained. See mate-h#19 at an attempt. - `scene_units_to_m` removed in favor of using `Transform` - Z up now possible by offsetting the viewer position to the equator - Floating origin systems now possible - Simplify the `AtmosphereBuffer` / `AtmosphereData` structs to just use the plain extracted `GpuAtmosphere` struct. this reduces the complexity of the struct in the mesh view bindings. Since atmosphere settings is coupled with the rendering pipeline of the atmosphere this makes sense architecturally. - We no longer hard code the offset to the north pole from the planet center in places. **Why not multi atmosphere:** The atmosphere uses multiple LUTs (lookup textures) to accelerate the rendering performance. Some of them are not view dependent: - Transmittance LUT - Multiple scattering LUT - Scattering / density LUTs These can be coupled and rendered for each atmosphere individually. However the remainder of the pipeline is view dependent: - Aerial View LUT - Sky View LUT - Render Sky pass In raymarched rendering mode, these LUTs can be skipped and only the render sky pass runs sampling on all of the atmospheres with a raymarch in screen space. Further, the Sky View LUT uses a local reference frame to concentrate texel density along the horizon's local up axis. This in turn means it's coupled with both a _specific_ atmosphere's local coordinates as well as the view's transform matrix. We cannot consider rendering both atmospheres into a single LUT for this reason. So it has to be unique for each pair of (view, atmosphere). Given two views and two atmospheres we would need 4 of these Sky View LUTs and at some point, raymarched rendering will become the less expensive option. Lastly the Render Sky pass needs to happen once per view, we cannot realistically composite them in sequence with simple dual-source blending as we do with the scene, this would result in incorrect scattering integration. This in turn means we need to bind ALL of the luts calculated previously so a single render sky pass and render aerial view lut - perhaps making use of array textures. Rely on unified volumetric ingegration in the raymarching loop: for each light,for each atmosphere, attenuate inscattering and transmittance along the path integral. It is suffice to say this change is overall _too complex_ for the time being and is likely the reason Unreal Engine also do not support multiple atmospheres. For context: our research is based heavily on Sebastian Hillarie's work, one of the Unreal graphics engineers. That being said about multiple atmospheres - I am thinking of this PR as a segway into unified volumetrics in Bevy. that is: Render the FogVolume and Atmosphere in a single pass! Making use of the frustum aligned voxel grid "froxel" approach to accelerate the rendering. This would drastically increase the performance for scenes wanting to make use of both the atmosphere and local fog volumes. ## Testing - Ran the `examples/3d/atmosphere.rs` example. --- ## Showcase (example screenshot unchanged compared to main.) ```rs // Spawn earth atmosphere commands.spawn(Atmosphere::earth(earth_medium)); commands.spawn(( Camera3d::default(), // Can be adjusted to change the rendering quality AtmosphereSettings::default(), )); ``` --------- Co-authored-by: Emerson Coskey <emerson@coskey.dev>
mate-h
added a commit
that referenced
this pull request
Apr 14, 2026
# Objective **Anecdotal feedback:** - no floating origin support for implementing large-scale worlds, forked Bevy's atmosphere at https://github.com/philpax/veldera/blob/main/crates/bevy_pbr_atmosphere_planet/NOTICE.md - no custom up axis support, resorted to using a custom sky shader for flight simulator with Z up coordinate system. Bevy's atmosphere appears tilted at a 90 degree angle with no way of changing it. ## Solution - Atmosphere component can be spawned stand-alone - AtmosphereSettings remains on camera - A closest-to-camera heuristic is used to pick the primary atmosphere to render. Deliberately no multi-atmosphere support to keep the scope of this PR small and self contained. See #19 at an attempt. - `scene_units_to_m` removed in favor of using `Transform` - Z up now possible by offsetting the viewer position to the equator - Floating origin systems now possible - Simplify the `AtmosphereBuffer` / `AtmosphereData` structs to just use the plain extracted `GpuAtmosphere` struct. this reduces the complexity of the struct in the mesh view bindings. Since atmosphere settings is coupled with the rendering pipeline of the atmosphere this makes sense architecturally. - We no longer hard code the offset to the north pole from the planet center in places. **Why not multi atmosphere:** The atmosphere uses multiple LUTs (lookup textures) to accelerate the rendering performance. Some of them are not view dependent: - Transmittance LUT - Multiple scattering LUT - Scattering / density LUTs These can be coupled and rendered for each atmosphere individually. However the remainder of the pipeline is view dependent: - Aerial View LUT - Sky View LUT - Render Sky pass In raymarched rendering mode, these LUTs can be skipped and only the render sky pass runs sampling on all of the atmospheres with a raymarch in screen space. Further, the Sky View LUT uses a local reference frame to concentrate texel density along the horizon's local up axis. This in turn means it's coupled with both a _specific_ atmosphere's local coordinates as well as the view's transform matrix. We cannot consider rendering both atmospheres into a single LUT for this reason. So it has to be unique for each pair of (view, atmosphere). Given two views and two atmospheres we would need 4 of these Sky View LUTs and at some point, raymarched rendering will become the less expensive option. Lastly the Render Sky pass needs to happen once per view, we cannot realistically composite them in sequence with simple dual-source blending as we do with the scene, this would result in incorrect scattering integration. This in turn means we need to bind ALL of the luts calculated previously so a single render sky pass and render aerial view lut - perhaps making use of array textures. Rely on unified volumetric ingegration in the raymarching loop: for each light,for each atmosphere, attenuate inscattering and transmittance along the path integral. It is suffice to say this change is overall _too complex_ for the time being and is likely the reason Unreal Engine also do not support multiple atmospheres. For context: our research is based heavily on Sebastian Hillarie's work, one of the Unreal graphics engineers. That being said about multiple atmospheres - I am thinking of this PR as a segway into unified volumetrics in Bevy. that is: Render the FogVolume and Atmosphere in a single pass! Making use of the frustum aligned voxel grid "froxel" approach to accelerate the rendering. This would drastically increase the performance for scenes wanting to make use of both the atmosphere and local fog volumes. ## Testing - Ran the `examples/3d/atmosphere.rs` example. --- ## Showcase (example screenshot unchanged compared to main.) ```rs // Spawn earth atmosphere commands.spawn(Atmosphere::earth(earth_medium)); commands.spawn(( Camera3d::default(), // Can be adjusted to change the rendering quality AtmosphereSettings::default(), )); ``` --------- Co-authored-by: Emerson Coskey <emerson@coskey.dev>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
No description provided.