-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Add MSAA option for Webgl2 #10052
Add MSAA option for Webgl2 #10052
Conversation
Pre let/const transition
Post let/const transition
Thanks for the pull request @ebogo1!
Reviewers, don't forget to make sure that:
|
@ebogo1 Just double checking - is this issue shown here also caused by the same issue that causes the Globe Translucency Sandcastle to fail? |
@sanjeetsuhag It's related - ideally I'd like to only recreate OIT's framebuffer resources when the number of samples has changed, but because OIT's update gets skipped during pick frames, this logic conflicts with disabling multisampling during pick frames. The OIT bugs can be fixed by not disabling multisampling during pick frames and recreating OIT resources only as needed, but picking is wonky when the scene color texture is antialiased - which is why I thought of the current approach initially. |
Awesome @ebogo1! We should update the jsdoc comments to include this option, and make it clear that for this option to work, Also for the top level option name, is it obvious that |
Babylon.js uses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1bfb1f1 adds _pickColorFramebuffer
to GlobeDepth for use only during pick frames. Whether or not its used is controlled by GlobeDepth._picking
, which is updated at the start of every frame in Scene.js (in updateAndClearFramebuffers
). There's also a new getter property in GlobeDepth for colorFramebufferManager
, which returns either the picking FramebufferManager or the main one.
The idea behind the change is to avoid recreating framebuffers and textures/renderbuffers whenever Scene switches to and from picking frames. On the Invert Classification Sandcastle, I see frames stay pretty consistent around 60 fps after this change, whereas before they dropped as low as 15 on my MacBook when MSAA was turned on and Picking frames were rendered (i.e. when clicking and dragging to pan the camera). This change should also fix the OIT issues from before.
@ggetz @lilleyse Any ideas about where the option should live in JSDoc? Currently it's only a member variable of Also I think that somewhere there should be a warning (similar to pickPosition/sampleHeights being unsupported when |
Yes, let's add it to the
Good idea, |
There should be an option on |
I added JSDoc lines for
WebGL isn't picky with the number of samples passed to functions like
Based on this, I didn't find issues on my MacBook by taking the minimum of |
I added a Sandcastle example with the BIM tileset, the Statue of Liberty, and the Hot Air Balloon model and MSAA options for 1x, 2x, 4x, and 8x in fd84fd9. I can also add an example with primitives like polylines if that'd be helpful. Should the Sandcastle live in the "Post Processing" category with FXAA? |
@lilleyse After CI passes this should be good for final review. I had it on my to-do list, but I don't think MSAA would work nicely with the OIT and EDL framebuffers for different reasons. OIT's transparent textures don't blend with the opaque scene texture until The only change in 496b1c1 was to remove an extra GlobeDepth blit before |
One user on the forum reported low frame rates on a 3090 (!) I checked that blitting and multisample framebuffers were being called as expected so I don't think there's an obvious reason for this. I get consistent performance on my MacBook and XPS with an NVIDIA card but I can reproduce low frames on a 3070 PC. After removing the last blit before pickDepth's update I gained around 10fps on the 3070 machine, but I still drop from ~144fps to 40 when in full screen after enabling MSAA. edit - @sanjeetsuhag was able to reproduce the frame drops on a 3080 and 1650M (XPS 15) running Windows 10 and 11. Interestingly, the same XPS did not drop frames on Linux, which is consistent with my XPS running Ubuntu. Not sure how common it is to blit depth attachments but I wonder if it's possible there's something there only on Windows. |
Offline we discussed that it might be possible to avoid the stencil blit in most cases. The only place where it might be needed is Even then, I'm not sure we need to do a stencil blit if we restructure the command a bit. Pasting a comment from slack that goes into more detail about these steps -
|
I realized the flaw with this idea. When |
Silver lining though - the stencil blit only needs to be cleared in |
@lilleyse If CI passes this should be good for another look. After 06190d3 I am seeing no frame drops on my 3070 machine. The change was to disable the
|
Source/Scene/Scene.js
Outdated
/** | ||
* The sample rate of multisample antialiasing (values greater than 1 enable MSAA). | ||
* @memberof Scene.prototype | ||
* @type {Boolean} | ||
* @readonly | ||
* @default false | ||
*/ | ||
msaaSamples: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type
and default
need to be fixed as well
It was easier to just push a fix for that 🤷♂️
Great! |
Fixes #9900.
This PR adds a
Scene.msaaSamples
option to enable multisampling in CesiumJS. This option is only available with Webgl2 contexts, which are accessible withrequestWebgl2
in the context options of theViewer
constructor.After this PR, the
FramebufferManager
class added in #9966 is able to construct aMultisampleFramebuffer
in place of a regularFramebuffer
. TheMultisampleFramebuffer
class is a wrapper around two framebuffers - one with multisampled render targets and another with textures that copy multisampled pixels during the blit. When multisampling is enabled, aFramebufferManager
will create both textures and corresponding (multisampled) renderbuffers for each attachment type and pass them to theMultisampleFramebuffer
constructor, which splits the attachments between its two framebuffers.The following framebuffers get multisampled when MSAA is enabled:
GlobeDepth._colorFramebuffer
: when globe depth is enabled, acts as the scene framebuffer with depth-stencil attachments. Since the other framebuffers inGlobeDepth
are used to store copies of the color framebuffer's textures, it is unnecessary to multisample the other framebuffers.InvertClassification._fbo
: when invert classification is enabled and translucent, it creates new depth stencil attachments for_fbo
that are later sampled in its translucent frag shader. Since the geometry is rendered to the main_fbo
,_fboClassified
does not need to be multisampled because it only needs access to the depth-stencil texture once it's ready.SceneFramebuffer._colorFramebuffer
: acts as the scene framebuffer when globe depth is disabled or when post process is enabled.To make testing easier, I made a small git patch to automatically add an MSAA dropdown to all Sandcastles and enable Webgl2 by default. There are a couple Sandcastles like Billboards that call
viewer.entities.removeAll()
in their reset functions, which will remove the entities if the MSAA mode is changed.Known issues:
To-do: