Skip to content

feat(WebGPU): Add Multiscale AntiAliasing to renderWindow#3417

Open
MaxKopacz wants to merge 3 commits intoKitware:masterfrom
MaxKopacz:feature/webgpu-msaa
Open

feat(WebGPU): Add Multiscale AntiAliasing to renderWindow#3417
MaxKopacz wants to merge 3 commits intoKitware:masterfrom
MaxKopacz:feature/webgpu-msaa

Conversation

@MaxKopacz
Copy link

@MaxKopacz MaxKopacz commented Feb 16, 2026

Context



Results


Before:

Screenshot 2026-02-16 at 14 30 41

After:

Screenshot 2026-02-16 at 14 32 08 ---

Changes

Added MSAA (Multi-Sample Anti-Aliasing) support to the WebGPU rendering backend. When enabled, both opaque and translucent geometry are rendered with 4× multisampling and resolved before compositing, reducing aliasing artifacts on geometry edges.

APIs added:
vtkWebGPURenderWindow
setSampleCount(count) / getSampleCount() — controls MSAA samples per pixel. Valid values: 1 (default, no AA) or 4. Invalid values are rejected with an error.
vtkWebGPURenderEncoder
setResolveTextureView(idx, view) — sets a resolve target texture view for a color attachment, used for MSAA resolve.
vtkWebGPUTexture
multiSample property (get) — exposes the sample count of the underlying GPU texture. Automatically propagated through - create(), resize(), and resizeToMatch().

Classes changed:
vtkWebGPUOpaquePass
— creates multisampled color/depth textures when sampleCount > 1, plus a 1-sample resolve color texture for downstream sampling.
getColorTextureView()
returns the resolved view when MSAA is active.
createRenderEncoder()
sets multisample.count in the pipeline settings.
vtkWebGPUOrderIndependentTranslucentPass
— creates multisampled OIT color and accumulation textures when sampleCount > 1, with corresponding resolve textures. The full-screen compositing quad reads from resolved textures during MSAA. Tears down and recreates resources on sampleCount change.
vtkWebGPURenderEncoder — attachTextureViews() now configures resolveTarget and sets storeOp: 'discard' on multisampled color attachments.
vtkWebGPURenderWindow — getPixelsAsync() reads from the resolve texture when MSAA is active.

Usage (js):
const renderWindow = vtkWebGPURenderWindow.newInstance();
renderWindow.setSampleCount(4); // enable 4× MSAA
renderWindow.setSampleCount(1); // disable MSAA (default)

  • Documentation and TypeScript definitions were updated to match those changes

PR and Code Checklist

  • semantic-release commit message
  • Run npm run reformat to have correctly formatted code

Testing

  • Tested environment:
  • vtk.js: master
  • OS: MacOS
  • Browser: Chrome
    testsuite name="Chrome 145.0.0.0 (Mac OS 10.15.7)" package="" timestamp="2026-02-17T15:47:38" id="0" hostname="Maxs-MacBook-Pro-2.local" tests="3212" errors="0" failures="1" time="0"> The error: [Rendering/Core/TextActor] Matching image - delta 4.06% (count: 6494)

This is not related to MSAA/OrderIndependentTranslucentPass changes. <- It will be due to my testing environment (I've not touched this code)

@MaxKopacz MaxKopacz changed the title Feature/webgpu msaa feat(WebGPU): Add Multiscale AnitAliasing to renderWindow Feb 16, 2026
@MaxKopacz MaxKopacz changed the title feat(WebGPU): Add Multiscale AnitAliasing to renderWindow feat(WebGPU): Add Multiscale AntiAliasing to renderWindow Feb 16, 2026
@jourdain jourdain requested a review from sankhesh February 16, 2026 16:30
Add configurable sampleCount to the WebGPU render pipeline:
- RenderWindow: expose setSampleCount()/getSampleCount() (default: 1)
- Texture: support sampleCount in create(), resize(), resizeToMatch()
- RenderEncoder: add resolveTextureViews for MSAA resolve targets
- OpaquePass: create multisampled color/depth textures when sampleCount > 1,
  with a resolved (1-sample) color texture for downstream sampling
- RenderWindow.getPixelsAsync: use resolved texture for readback when MSAA active

Usage:
  const gpuRenderWindow = vtkWebGPURenderWindow.newInstance();
  gpuRenderWindow.setSampleCount(4); // Enable 4x MSAA
@sankhesh
Copy link
Collaborator

@MaxKopacz Thanks for the contribution and for the clear description of the changes and testing you’ve already done.

Could you also add a regression test (or extend an existing one) that exercises MSAA support? That will help ensure future changes don’t accidentally break this behavior and will make it easier for us to catch regressions in CI.

'presentationFormat',
'useBackgroundImage',
'xrSupported',
'sampleCount',
Copy link
Member

Choose a reason for hiding this comment

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

in the VTK C++ world, it is called multiSample. Can you please reuse the same naming convention?

// first
// This pass implements a forward rendering pipeline for translucent geometry.
// It uses order-independent transparency (OIT) with weighted blended
// compositing, reading the opaque depth buffer for depth testing.
Copy link
Member

Choose a reason for hiding this comment

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

@sankhesh is the OIT pass really alpha blending in VTK.js ? According to Lucas Gandel, it is not just an alpha blending pass in VTK (hence there would be more to do here).

@MaxKopacz
Copy link
Author

MaxKopacz commented Feb 17, 2026

@MaxKopacz Thanks for the contribution and for the clear description of the changes and testing you’ve already done.

Could you also add a regression test (or extend an existing one) that exercises MSAA support? That will help ensure future changes don’t accidentally break this behavior and will make it easier for us to catch regressions in CI.

I wrote a quick test which fires up a webGPU renderwindow and tests some primitive shapes with and without multiSample. As far as I am aware this will be the first webGPU related test, and will only run if webGPU is available in the browser and with npm run test:webgpu (which runs chrome canary - I don't have this installed so I set the WEBGPU=1 flag as chrome has had webGPU supported by default since Chrome 113). As such i am unaware if this is the correct testing approach and am happy to revert. Please note, I am bandwidth limited so I have not architected any of this with much thought.

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.

3 participants