SSRNode: Improve performance and add quality setting. #31576
Merged
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.
Related issue: -
Description
The PR improves the performance of
SSRNode
by removing an outdated check inside the raymarching loop which was necessary for a Chromium bug. Since this bug is fixed since 133 (see here), I think it's safe to remove it. Anotherif
can be removed by simplifying how the raymarching loop is configured. Removing bothif
statements produce some extra frames so this is a nice performance plus.While reviewing other SSR implementations I have realized that
SSRNode
has a very high sampling rate inside the raymarching loop. Meaning it checks every pixel that lies on a ray's path which is the maximum possible quality. No SRR implementation I have checked so far uses such a setting by default. An implementation for Unity uses80
samples and a value range of[20,80]
and Lettier's approach uses a scaling factor in the range[0,1]
. I have adapted this approach toSSRNode
with the same default value of0.5
. That means only half of the pixels on the ray are processed. That setting is a uniform so it is configurable on app level. Even with0.5
, you barely see a quality difference. However, in a performance restricted test with a 5K resolution, performance went up from 29 to 52 FPS.You can explore the new
quality
parameter in the updated example. Below is the one in production for comparison:https://rawcdn.githack.com/mrdoob/three.js/75456f3498d9e213fbfe282d2cafda5cb4035cf8/examples/webgpu_postprocessing_ssr.html
https://threejs.org/examples/webgpu_postprocessing_ssr
I'm going to invest more time in
SSRNode
since there is still a lot of room for improvements. I'd like to test the raymarching loop from the Unity effect which works a bit different than ours. Besides, I've seen it supports mipmaps which means you can create blurred samples of the SSR reflections and then pick a mip based on the fragment's roughness. That is a similar approach like PMREM. Since this is quite heavy, it's an optional feature but of course worth checking out. Another thing is that some SSR implementations also have a temporal component which means they use a jitter in their ray marching process to produce different SSR reflections over time. The results are then accumulate similar to TRAA. There are different strategies of implementing such a feature and some of them are quite complex (e.g. "Stochastic Screen-Space Reflections") but it is definitely worth investigating.