-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Procedural Atmosphere PBR integration #19037
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
base: main
Are you sure you want to change the base?
Conversation
More robust test scene includes camera and sun controller(with right click) and switching between earth, mars, raymarched vs default rendering: |
This seems to be several changes under one umbrella. Do you think it's at all feasible to split this into multiple PRs? It'd be much easier to review piecewise but I understand it might well be a lot of work. No worries if that's the case |
It's definitely feasible the only reason I didn't, is because I am not certain that will ultimately be less work to review. But i could start by splitting out the PBR directional light part since it's fairly isolated. But the new ray-marching function is used throughout, so that part might be more challenging. How many smaller pieces would make sense? |
Eh, I guess not all that important after my first pass. It's honestly pretty well-structured and somewhat interrelated. I'll trust you're right about what's less review work. If you want to break it up, I think the light probe stuff looks pretty well-isolated, and the directional light stuff like you said. But again, I'm no longer convinced it'd be better like that. |
After some discussion I decided it's best to de-couple the SPD and pre-filtering pipeline changes in a separate PR, but keeping everything atmosphere-related here, and in the other PR I will still reference this one for the description and use-case. |
It looks like your PR has been selected for a highlight in the next release blog post, but you didn't provide a release note. Please review the instructions for writing release notes, then expand or revise the content in the release notes directory to showcase your changes. |
Objective
Currently Bevy's atmosphere solution does not extend to include the PBR pipeline, it is merely a composited effect on top of the scene using blend operations. The goal of this pull request is to provide realistic, physically-based lighting to any geometry in an outdoor scene, covering a vast number of use cases for game developers.
Solution
We achieve this using a combination of the following features:
More specific implementation details:
rendering_method
parameter to theAtmosphereSettings
which includes more precise volumetric shadows and enables space viewsorigin
parameter to theAtmosphere
which controls the observers position, enabling space views for using the raymarched rendering methodSunLight
component that controls the size of the sun disk rendered in the atmosphere and defaulted it to the mean value taken from scientific dataShared ray-marching function
Shared ray-marching function in the atmosphere shader, except for the aerial-view LUT. For the Aerial-view LUT we have two nested for loops, and we march the ray further and further for each depth slice so it's slightly different.
The shared ray-marching function has the following signature:
Since WGSL has no function overloading (see open issue), the caller has to supply all arguments. I also wanted to specifically avoid using a struct as an input to make the resulting called code more concise, at the sacrifice of readability. Because the function signature can easily be looked up, I didn't think this was an issue.
Caller code example:
Proposal: additional parameter to control whether to apply the shadowing term for computing volumetric shadows.
PBR Directional light
PBR directional lights are occluded by the transmittance through the atmosphere, getting tinted orange, then red when the sun is low over the horizon.
pbr_lighting.wgsl
file'sdirectional_light
function to extend it to the atmospheric transmittance.Generated Environment Map Light
In order to generate an environment map, we place a light probe into the world and attach the
AtmosphereEnvironmentMapLight
component to it. Given it's transform in the world, we create an environment map at that location, by running the atmosphere shader ray-marching for each cube face. Note how we need to create a separate view (2d storage texture array) and re-interpret it at runtime, using the create view function.ECS flow:
LightProbe
andAtmosphereEnvironmentMapLight
AtmosphereEnvironmentMapLight
is extracted withExtractComponentPlugin
prepare_atmosphere_probe_components
addsFilteredEnvironmentMapLight
andAtmosphereEnvironmentMap
create_environment_map_from_prefilter
addsEnvironmentMapLight
based on theFilteredEnvironmentMapLight
Single Pass downsampling (SPD) pipeline:
Pre-filtering pipeline: composed of multiple Radiance Map (specular mips) generation passes, followed by the irradiance map pass (diffuse).
The pre-filtering pipeline is largely based on these articles:
Render Graph:

Testing
Showcase
Usage:
Notes for reviewers
In it's current state, this PR includes a lot of code that may not need to be merged into the
main
branch. Therefore I am looking for feedback which changes to eliminate before proceeding any more work on it.Given that all this work is done, but how large this pull request is may make it difficult to review all at once. I'm also looking for feedback whether it is better/more efficient to split it into smaller ones, for example:
Next Steps
ground
,jitter
, andshadow
parameters per-render pass and screenshots that show the results