Implement opt-in sharp screen-space reflections for the deferred renderer.#12959
Implement opt-in sharp screen-space reflections for the deferred renderer.#12959pcwalton wants to merge 12 commits intobevyengine:mainfrom
Conversation
|
The generated |
2cb94e1 to
f44dfb3
Compare
|
This should be ready for review now. |
renderer. This commit implements *screen-space reflections* (SSR), which approximate real-time reflections based on raymarching through the depth buffer and copying samples from the final rendered frame. Numerous variations and refinements to screen-space reflections exist in the literature. This patch foregoes all of them in favor of implementing the bare minimum, so as to provide a flexible base on which to customize and build in the future. For a general basic overview of screen-space reflections, see [1]. The raymarching shader uses the basic algorithm of tracing forward in large steps (what I call a *major* trace), and then refining that trace in smaller increments via binary search (what I call a *minor* trace). No filtering, whether temporal or spatial, is performed at all; for this reason, SSR currently only operates on very shiny surfaces. No acceleration via the hierarchical Z-buffer is implemented (though note that bevyengine#12899 will add the infrastructure for this). Reflections are traced at full resolution, which is often considered slow. All of these improvements and more can be follow-ups. SSR is built on top of the deferred renderer and is currently only supported in that mode. Forward screen-space reflections are possible albeit uncommon (though e.g. *Doom Eternal* uses them); however, they require tracing from the previous frame, which would add complexity. This patch leaves the door open to implementing SSR in the forward rendering path but doesn't itself have such an implementation. Screen-space reflections *are* supported in WebGL 2. To add screen-space reflections to a camera, use the `ScreenSpaceReflections` component. `DepthPrepass` and `DeferredPrepass` must also be present for the reflections to show up. The `ScreenSpaceReflections` component contains several settings that artists can tweak, and also comes with sensible defaults. A new example, `ssr`, has been added. It's loosely based on the [three.js ocean sample], but all the assets are original. Note that the three.js demo has no screen-space reflections and instead renders a mirror world. Additionally, this patch fixes a random bug I ran across: that the `"TONEMAP_METHOD_ACES_FITTED"` `#define` is incorrectly supplied to the shader as `"TONEMAP_METHOD_ACES_FITTED "` (with an extra space) in some paths. [1]: https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html [three.js ocean sample]: https://threejs.org/examples/webgl_shaders_ocean.html
|
I renamed |
|
Don't have time for a review, but saw the request. Just wanted to note that specular occlusion should use SSR if it is available. I believe I cited some papers in the shader code that talk about how to use SSR with specular occlusion. This might be out of scope, but it popped in my head when I saw this. |
|
@aevyrie Yes, I agree. I think that should be a followup as it'll be a decent amount of code. |
|
The example crashes if any other prepasses are added to the camera, for example I believe the |
|
@chronicl Fixed, thanks! |
JMS55
left a comment
There was a problem hiding this comment.
Works surprisingly well with TAA, I was expecting the reflections to cause issues.
A bit surprised that the water reflection from the envmap is part of SSR, and not just part of the PBR shader, but maybe there's a good reason for that.
Some weird shader defs / things that stand out to me about how SSR is setup on the CPU. Not sure it's entirely right (although, it does work).
This PR is going to conflict with the clearcoat PR, probably want to merge that one first.
| /// [`DeferredPrepass`] to the camera as well. | ||
| /// | ||
| /// SSR currently performs no roughness filtering for glossy reflections, so | ||
| /// only very smooth surfaces will reflect objects in screen space. You can |
There was a problem hiding this comment.
Please link to the StandardMaterial roughness property here.
|
|
||
| for (view, ssr_settings) in views.iter() { | ||
| let uniform_offset = match ssr_settings { | ||
| None => 0, |
There was a problem hiding this comment.
What's going on here? Why not use UniformComponentPlugin or similar?
crates/bevy_pbr/src/ssr/mod.rs
Outdated
| let mut shader_defs = vec. For a general basic overview of screen-space reflections, see [1](https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html). The raymarching shader uses the basic algorithm of tracing forward in large steps, refining that trace in smaller increments via binary search, and then using the secant method. No temporal filtering or roughness blurring, is performed at all; for this reason, SSR currently only operates on very shiny surfaces. No acceleration via the hierarchical Z-buffer is implemented (though note that #12899 will add the infrastructure for this). Reflections are traced at full resolution, which is often considered slow. All of these improvements and more can be follow-ups. SSR is built on top of the deferred renderer and is currently only supported in that mode. Forward screen-space reflections are possible albeit uncommon (though e.g. *Doom Eternal* uses them); however, they require tracing from the previous frame, which would add complexity. This patch leaves the door open to implementing SSR in the forward rendering path but doesn't itself have such an implementation. Screen-space reflections aren't supported in WebGL 2, because they require sampling from the depth buffer, which Naga can't do because of a bug (`sampler2DShadow` is incorrectly generated instead of `sampler2D`; this is the same reason why depth of field is disabled on that platform). To add screen-space reflections to a camera, use the `ScreenSpaceReflectionsBundle` bundle or the `ScreenSpaceReflectionsSettings` component. In addition to `ScreenSpaceReflectionsSettings`, `DepthPrepass` and `DeferredPrepass` must also be present for the reflections to show up. The `ScreenSpaceReflectionsSettings` component contains several settings that artists can tweak, and also comes with sensible defaults. A new example, `ssr`, has been added. It's loosely based on the [three.js ocean sample](https://threejs.org/examples/webgl_shaders_ocean.html), but all the assets are original. Note that the three.js demo has no screen-space reflections and instead renders a mirror world. In contrast to #12959, this demo tests not only a cube but also a more complex model (the flight helmet). ## Changelog ### Added * Screen-space reflections can be enabled for very smooth surfaces by adding the `ScreenSpaceReflections` component to a camera. Deferred rendering must be enabled for the reflections to appear.  
This commit implements screen-space reflections (SSR), which approximate real-time reflections based on raymarching through the depth buffer and copying samples from the final rendered frame. Numerous variations and refinements to screen-space reflections exist in the literature. This patch foregoes all of them in favor of implementing the bare minimum, so as to provide a flexible base on which to customize and build in the future.
For a general basic overview of screen-space reflections, see 1. The raymarching shader uses the basic algorithm of tracing forward in large steps (what I call a major trace), and then refining that trace in smaller increments via binary search (what I call a minor trace). No filtering, whether temporal or spatial, is performed at all; for this reason, SSR currently only operates on very shiny surfaces. No acceleration via the hierarchical Z-buffer is implemented (though note that #12899 will add the infrastructure for this). Reflections are traced at full resolution, which is often considered slow. All of these improvements and more can be follow-ups.
SSR is built on top of the deferred renderer and is currently only supported in that mode. Forward screen-space reflections are possible albeit uncommon (though e.g. Doom Eternal uses them); however, they require tracing from the previous frame, which would add complexity. This patch leaves the door open to implementing SSR in the forward rendering path but doesn't itself have such an implementation. Screen-space reflections are supported in WebGL 2.
To add screen-space reflections to a camera, use the
ScreenSpaceReflectionsBundlebundle or theScreenSpaceReflectionsSettingscomponent. In addition toScreenSpaceReflectionsSettings,DepthPrepassandDeferredPrepassmust also be present for the reflections to show up. TheScreenSpaceReflectionsSettingscomponent contains several settings that artists can tweak, and also comes with sensible defaults.A new example,
ssr, has been added. It's loosely based on the three.js ocean sample, but all the assets are original. Note that the three.js demo has no screen-space reflections and instead renders a mirror world.Additionally, this patch fixes a random bug I ran across: that the
"TONEMAP_METHOD_ACES_FITTED"#defineis incorrectly supplied to the shader as"TONEMAP_METHOD_ACES_FITTED "(with an extra space) in some paths.Changelog
Added
ScreenSpaceReflectionscomponent to a camera. Deferred rendering must be enabled for the reflections to appear.