-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Solari: Dynamic realtime global illumination #10000
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
Conversation
This reverts commit cdf0271.
@JMS55 What happened? Did it just get too far behind or something? |
A couple of things:
I am really looking forward to coming back to this in the future, but wgpu needs to support raytracing first. Realtime RT-GI is super cool, and since I started this project there's been even more exciting papers, but I don't have the time or motivation to keep trying to patch wgpu and bevy. If anyone would like to see this work continue, please contribute raytracing support to wgpu along with the tests it needs to get merged. |
I'm working on pushing RT support in wgpu with express motivation to get some ReSTIR lighting approaches into bevy. |
Hey, glad to see more people interested in RT! Wgpu's current RT support is actually good enough for me to start working on RT DI/GI. The main blockers are no longer RT related:
When these are resolved I plan to revive Solari. |
I'm still studying the internals and how wgpu works. My plan is to help mature the RT stack on wpgu side first - compaction, in-place update of accel structures, then work my way up to binding arrays. |
# Bevy Solari <img src="https://github.com/user-attachments/assets/94061fc8-01cf-4208-b72a-8eecad610d76" width="100" /> ## Preface - See release notes. - Please talk to me in #rendering-dev on discord or open a github discussion if you have questions about the long term plan, and keep discussion in this PR limited to the contents of the PR :) ## Connections - Works towards #639, #16408. - Spawned #18993. - Need to fix RT stuff in naga_oil first bevyengine/naga_oil#116. ## This PR After nearly two years, I've revived the raytraced lighting effort I first started in #10000. Unlike that PR, which has realtime techniques, I've limited this PR to: * `RaytracingScenePlugin` - BLAS and TLAS building, geometry and texture binding, sampling functions. * `PathtracingPlugin` - A non-realtime path tracer intended to serve as a testbed and reference. ## What's implemented?  * BLAS building on mesh load * Emissive lights * Directional lights with soft shadows * Diffuse (lambert, not Bevy's diffuse BRDF) and emissive materials * A reference path tracer with: * Antialiasing * Direct light sampling (next event estimation) with 0/1 MIS weights * Importance-sampled BRDF bounces * Russian roulette ## What's _not_ implemented? * Anything realtime, including a real-time denoiser * Integration with Bevy's rasterized gbuffer * Specular materials * Non-opaque geometry * Any sort of CPU or GPU optimizations * BLAS compaction, proper bindless, and further RT APIs are things that we need wgpu to add * PointLights, SpotLights, or skyboxes / environment lighting * Support for materials other than StandardMaterial (and only a subset of properties are supported) * Skinned/morphed or otherwise animating/deformed meshes * Mipmaps * Adaptive self-intersection ray bias * A good way for developers to detect whether the user's GPU supports RT or not, and fallback to baked lighting. * Documentation and actual finalized APIs (literally everything is subject to change) ## End-user Usage * Have a GPU that supports RT with inline ray queries * Add `SolariPlugin` to your app * Ensure any `Mesh` asset you want to use for raytracing has `enable_raytracing: true` (defaults to true), and that it uses the standard uncompressed position/normal/uv_0/tangent vertex attribute set, triangle list topology, and 32-bit indices. * If you don't want to build a BLAS and use the mesh for RT, set enable_raytracing to false. * Add the `RaytracingMesh3d` component to your entity (separate from `Mesh3d` or `MeshletMesh3d`). ## Testing - Did you test these changes? If so, how? - Ran the solari example. - Are there any parts that need more testing? - Other test scenes probably. Normal mapping would be good to test. - How can other people (reviewers) test your changes? Is there anything specific they need to know? - See the solari.rs example for how to setup raytracing. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? - Windows 11, NVIDIA RTX 3080. --------- Co-authored-by: atlv <email@atlasdostal.com> Co-authored-by: IceSentry <IceSentry@users.noreply.github.com> Co-authored-by: Carter Anderson <mcanders1@gmail.com>
WARNING: Highly experimental, will not be merged anytime soon.
Here's a pretty image so the PR isn't entirely text, but keep in mind there's still a lot of work needed to get this to a generally usable and artifact/bug-free state.
Overview
Solari is an implementation of fully dynamic, fully realtime raytraced global illumination. All lights and objects can move and mutate, contribute indirect lighting (including emissive meshes), and receive indirect light bounces. It's comparable in scope to Unreal Engine 5's Lumen (Fortnite, Lumen in the Land of Nanite), or Nvidia's RTXGI (Cyberpunk 2077).
This is a high end GPU-intensive rendering technique. All testing was done on an RTX 3080 GPU, at both 1080p and 4k, with an initial target budget of around 4ms of GPU time (ideally we can get this down to ~2ms with further optimizations). As it relies on hardware raytracing support, it only works on GPUs such as Nvidia's RTX 2000 series+, and AMD's RX 6000 series+. Currently, this PR is using an experimental fork of wgpu that implements hardware raytracing on the Vulkan backend only. Metal and DirectX12 are not currently supported.
Note that Solari only (currently) does indirect diffuse lighting. Indirect specular lighting (reflections) will come later, and raytraced direct diffuse and specular lighting much later as part of a separate sub-plugin of Solari, likely using a different technique.
Current Technique
The following is a simple high-level overview of Solari's current rendering, as details are extremely subject to change and I don't want to have to rewrite this frequently. A detailed breakdown will probably come once everything is actually finished. See the literature section of this PR description for links to each of the techniques.
Like Lumen and specifically GI-1.0, Solari uses a multi-level radiance/irradiance cache. The high level process is as follows:
The final path is as such: camera -> visible point on screen (probe placed) -> a different point in the world (world cache queried) -> light sources. GI-1.0 has a great illustration of this:

A more detailed, technical breakdown is as follows:
TODOs
See
crates/bevy_pbr/src/solari/todo.txt
.Expect lots of bugs, ghosting, light leaks, quality issues, etc. Especially in non-toy scenes. Anything in
bevy_pbr::solari::scene
should be treated as temporary, and only written in order to let me work on the actual shader techniques.This is a draft PR, and will likely remain that way for a long while. I've been working on this basically solo for months already, and expect to continue doing so for many more months. That said, I'm putting this out there in the hopes of raising additional help developing Solari. If you're interested in helping with the development, please reach out on the rendering-dev channel in Bevy's discord!
Blockers
All of these are currently worked around either in Bevy (along with other hacks), or hacked around in forked dependencies.
Other missing nice-to-haves for better performance:
Literature
Thanks
Finally, I'd like to thank Alexander Sannikov for his help understanding and implementing his radiance cascades technique, @daniel-keitel for their work implementing raytracing support in wgpu, and countless others in the Bevy discord, wgpu/naga communities, and other graphics forums that have given me advice on this project. Far too many people to name individually :)