mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.64k stars 35.37k forks source link

Multisampling over Multiple Render Target #23300

Closed RenaudRohlinger closed 2 years ago

RenaudRohlinger commented 2 years ago

Hello! WebGL2 enables MSAA which is a great antialiasing feature. On top of that, the recent introduction of Multiple Render Target on threejs allowed us to do some deferred rendering which is amazing!

On the postprocessing GitHub repository, we were talking about trying to do antialiasing over MRT and it ends up combining both of these two technologies would be the best solution: https://github.com/vanruesc/postprocessing/issues/333

As mentioned here MRT + MSAA should be supported in WebGL 2.

I've been trying to make it work but without any success, as mentioned on the forum 😢

Would it be something threejs would be willing to support in the future? Did anyone ever try?

gkjohnson commented 2 years ago

Do note that MSAA + MRT is not a magic bullet for AA with deferred rendering-style postprocessing effects. Specifically in cases where you need to use reconstructed geometry information for an effect (ie sceen space ambient occlusion, reflections, etc). There are plenty of cases where it would work, though, depending on the effect.

The wiki page on deferred rendering touches on the topic:

hardware anti-aliasing does not produce correct results anymore since interpolated subsamples would result in nonsensical position, normal, and tangent attributes.

https://en.wikipedia.org/wiki/Deferred_shading

RenaudRohlinger commented 2 years ago

Ah yes, I understand thanks for the heads up @gkjohnson. I think a pretty efficient setup is actually a combination of forward and deferred rendering, especially with threejs.

For example, we could render all the materials using forward rendering, and let's say we want to do selective bloom or apply an effect only on some areas, then MRT will be pertinent as we would not have to render multiple times the glowing objects. That way we would use MRT more as postprocessing than a deferred rending feature.

marcofugaro commented 2 years ago

You can use WebGLMultisampleRenderTarget for the color pass to get native antialiasing when using multiple render targets.

Look here: https://github.com/spite/genuary-2022/blob/05230601cfc161e1689b3856c3ba5bdd9e4b7403/modules/fbo.js#L12

And specifically the dices example where he uses SSAO with MRT: https://github.com/spite/genuary-2022/tree/main/24

RenaudRohlinger commented 2 years ago

Thanks for the reference! In your example, if I understand correctly the concept is about rendering twice the whole scene, first, one time in a WebGLMultisampleRenderTarget, then a second time in an MRT.

What I was talking about was just to render one time the scene in an MRT and then be able to apply multisampling over each layout. This practice could be useful if we want to add a particular selective effect while rendering the whole scene only once and still making use of the multisample antialiasing.

CodyJasonBennett commented 2 years ago

I tried implementing this from scratch here: https://codesandbox.io/s/webgl-multi-sampled-mrt-fbos-1vhkif

Some notes (I'll repeat the obvious for the sake of being on the same page):