Skip to content
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

Addons: Add SSRNode. #29597

Merged
merged 4 commits into from
Oct 9, 2024
Merged

Addons: Add SSRNode. #29597

merged 4 commits into from
Oct 9, 2024

Conversation

Mugen87
Copy link
Collaborator

@Mugen87 Mugen87 commented Oct 9, 2024

Related issue: #29295

Description

This PR ports SSRPass to WebGPURenderer as SSRNode. I have not ported all features yet (bouncing) since I'd like to focus on the existing open issues first.

Good things first: Instead of 3 passes (beauty/depth + normals + metalness), SSRNode now gets its (shared) inputs with just one pass thanks to MRT (🎉 ). Besides, #21487 should be partly solved since the implementation use the metalness() TSL function to render the actual metalness values of the materials. What's missing is some sort of attenuation during the SSR blending that depends on the metalness/roughness values.
Finally, SSRNode performs no hierarchy traversal like SSRPass does for its metalness rendering which is also a plus in performance.

The bad thing is that the fragment shader (to be more precise the raymarching portion) runs poorly in WGSL. On a mac Mini with M2 Pro and a 5K resolution I get just 42 FPS. With WebGL, I get the expected 60 FPS. So that needs a closer investigation. Especially since the SSR already runs at half resolution (you can tweak this via a resolutionScale property).

I took the time to document the ssr() TSL function since I bet there is some room for refactoring and performance improvements. We might want to study different SSR implementations to further improve this one. Inputs from the community are welcome!

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 9, 2024

Regarding the blur: I think it's better to keep it out of SSRNode and use e.g. GaussianBlurNode and connect it to the output of SSRNode. E.g.

const blurPass = gaussianBlur( ssr.getTextureNode() );

I've tried that in the demo but the blurred SSR gets darken edges. Not sure why that happens yet.

Blur:

image

No Blur:

image


// blend SSR over beauty

const outputNode = vec4( scenePass.rgb.mul( ssrPass.a.oneMinus() ).add( ssrPass.rgb.mul( ssrPass.a ) ), scenePass.a );
Copy link
Collaborator Author

@Mugen87 Mugen87 Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunag This imitates the previous normal blending but I hope we can find an easier way to blend the reflective colors onto the beauty pass.

@sunag
Copy link
Collaborator

sunag commented Oct 9, 2024

I've tried that in the demo but the blurred SSR gets darken edges. Not sure why that happens yet.

I think we need to add opacity support in gaussianBlur(). I had a similar problem a few weeks ago, I think it's the same thing.

@sunag
Copy link
Collaborator

sunag commented Oct 9, 2024

The bad thing is that the fragment shader (to be more precise the raymarching portion) runs poorly in WGSL. On a mac Mini with M2 Pro and a 5K resolution I get just 38 FPS. With WebGL, I get the expected 60 FPS. So that needs a closer investigation. Especially since the SSR already runs at half resolution (you can tweak this via a resolutionScale property).

Sharing my results with FPS limiter turned off.

  • WebGPURenderer - ~3500 FPS ( WebGL Backend )
  • WebGPURenderer - ~3150 FPS ( WebGPU Backend )
  • WebGLRenderer - ~1300FPS

The new approach is much more performant. 🎉🎉🎉

@Mugen87 Mugen87 added this to the r170 milestone Oct 9, 2024
@Mugen87 Mugen87 merged commit 1a6d5e6 into mrdoob:dev Oct 9, 2024
11 checks passed
@mrdoob
Copy link
Owner

mrdoob commented Oct 10, 2024

FYI @gonnavis

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 10, 2024

I've tried that in the demo but the blurred SSR gets darken edges. Not sure why that happens yet.

Just want to confirm that the new premultipliedGaussianBlur() solves this issue 🎉. So everyone who wants to soften the SSR reflections can use this:

const blurPass = premultipliedGaussianBlur( ssr.getTextureNode(), 0.5 );

The second parameter controls the intensity of the blur. IMO, a subtle blur should be sufficient for most use cases.

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 10, 2024

The bad thing is that the fragment shader (to be more precise the raymarching portion) runs poorly in WGSL. On a mac Mini with M2 Pro and a 5K resolution I get just 42 FPS. With WebGL, I get the expected 60 FPS. So that needs a closer investigation.

Did some more testing and on Safari with enabled WebGPU the demo runs flawless with 60 FPS on the same device. But latest Chrome and even Chrome Canary have performance issues with the SSR demo. I suspect this is related to loop-heavy WGSL code.

Before I report a bug at the Chromium bug tracker, I would appreciate if someone with a Mac (M processor) can test the SSR demo with Chrome and Safari. If the frame rate is slower in Chrome, it's probably the same issue.

https://rawcdn.githack.com/mrdoob/three.js/dev/examples/webgpu_postprocessing_ssr.html

@gonnavis
Copy link
Contributor

Hello @Mugen87 , tried on my mac that, can run at 120 fps (Full fps?) on both Chrome and Firefox.
And for Chrome, it's interesting that will increase fps after rotate.

Chrome (Just open and wait, do nothing): 85 fps
image

Chrome (Do some rotate): 120 fps
image

Firefox: 120 fps
image

image image image

@gonnavis
Copy link
Contributor

Umm, no, not stable, tried again that only showing about 80 fps.
And the real feeling very laggy, like below 10 fps.
I don't think changed many opening softwares.

image

@gonnavis
Copy link
Contributor

Oh, the low fps caused by opening the page on Chrome and Firefox simultaneously.
Back to 120 fps and very fluent again after close one, only opening one.

@gonnavis
Copy link
Contributor

gonnavis commented Oct 10, 2024

Low fps when viewing from bottom to top (Even only opening one page) on Chrome.
Fine for Firefox.

Chrome: around 30 fps
image

Firefox: 120 fps
image

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 10, 2024

Thanks for your feedback!

The viewing angle influences the runtime behavior/complexity of the ray marching. However, if the FPS reacts so sensitive in Chrome, it suspect the same performance issue on your device.

@gonnavis
Copy link
Contributor

the FPS reacts so sensitive in Chrome, it suspect the same performance issue on your device.

Yea I think so.
Fine on Firefox, still full 120 fps when viewing from bottom to top.

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 10, 2024

Bug report: https://issues.chromium.org/issues/372714384

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants