Atmosphere as entity with transforms#23651
Conversation
|
Thanks! Eagerly waiting for this 😄 |
ecoskey
left a comment
There was a problem hiding this comment.
Ooh nice! Mostly just have some nitpicks and some comments for future work.
crates/bevy_light/src/atmosphere.rs
Outdated
| /// when your scene uses other units, like kilometer-sized scenes. | ||
| #[derive(Clone, Component)] | ||
| #[require(Hdr)] | ||
| #[require(Transform::default())] |
There was a problem hiding this comment.
Why does the north pole of a sphere matter? Why does up direction matter at all? Isn't scattering entirely view, medium, and light dependent?
There was a problem hiding this comment.
Do you mean regarding the default Vec3::NEG_Y * radius offset? I think it's just that most people will want the planet normal to be Vec3::Y around where their scene is located. But yeah the docs should probably say that instead of making the north pole special.
There was a problem hiding this comment.
Yes the north pole is not special in any sense, there is no global up direction. the locally apparent up direction from the planets surface (i.e. the way the horizon faces) arises from the spheres outward pointing normal direction. Since bevy's convention is Y up by default that's why I also defaulted the scene to align the horizon with this up direction. If the user were to tilt there camera to be Z up for instance they would need to move the atmosphere offset to the equator instead so the apparent horizon's tilt also matches the new up direction. Hope this clears things up a bit. This is in contrast to the linked repo above that encodes the local up direction into the atmosphere space during the inner raymarch. Code ref: https://github.com/philpax/veldera/blob/main/crates/bevy_pbr_atmosphere_planet/src/shaders/functions.wgsl#L230
this effectively rotates the horizon in view space relative to the camera which works differently than a simple transform on the atmosphere component. so I deliberately excluded this type of approach from this PR.
Co-authored-by: Emerson Coskey <emerson@coskey.dev>
|
The generated |
There was a problem hiding this comment.
Looks good! Agree that we shouldn't hold this up too long on renaming or other refactors. Approving 🙂
- I do still think we can save three matmuls in
ndc_to_camera_distif the planet's scale is uniform (which it should always be imo) and we keep track of the scale separate from the matrix. - I'm fine with keeping
AtmosphereSettingsas the "driver" component for now, but will note that we moved away from this style in several other effects. i.e.BloomSettingswas renamed toBloomiirc
Objective
Anecdotal feedback:
Solution
scene_units_to_mremoved in favor of usingTransformAtmosphereBuffer/AtmosphereDatastructs to just use the plain extractedGpuAtmospherestruct. 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.Why not multi atmosphere:
The atmosphere uses multiple LUTs (lookup textures) to accelerate the rendering performance. Some of them are not view dependent:
These can be coupled and rendered for each atmosphere individually. However the remainder of the pipeline is view dependent:
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
examples/3d/atmosphere.rsexample.Showcase
(example screenshot unchanged compared to main.)