Skip to content

fix(xr): visionOS MSAA resolve into XR framebuffer#8730

Merged
mvaligursky merged 3 commits into
mainfrom
mv-fix-avp-msaa-xr-resolve
May 15, 2026
Merged

fix(xr): visionOS MSAA resolve into XR framebuffer#8730
mvaligursky merged 3 commits into
mainfrom
mv-fix-avp-msaa-xr-resolve

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Fixed #7410

Working WebXR with MSAA on Apple Vision Pro. Previously the only way to get a usable image on AVP was to disable anti-aliasing, because the engine's MSAA resolve uses gl.blitFramebuffer directly into the XRWebGLLayer's opaque framebuffer — a path that visionOS WebKit handles incorrectly, producing a small zoomed-in sub-region instead of full stereo content.

Fix: on visionOS only, MSAA color is resolved into an internal scratch texture via blitFramebuffer, then copied 1:1 into the XR framebuffer with a single fullscreen textured quad. The rasterization path is what AVP renders correctly.

Changes:

  • Added pc.platform.visionos boolean — detects Apple Vision Pro. visionOS Safari spoofs a macOS UA (no "visionOS" string), so detection combines Macintosh UA + maxTouchPoints > 0 + no iPhone/iPad/iPod token.
  • New internal WebglXrMsaaCopy helper — owns a scratch Texture/RenderTarget and a fullscreen-quad copy shader, built via Shader, ShaderDefinitionUtils, and device.scope. Lazily created on WebglGraphicsDevice, only on visionOS.
  • WebglRenderTarget.resolve routes XR color resolves through the helper when platform.visionos is true; all other XR platforms (Quest, Chrome, etc.) keep the existing direct-blit path with zero overhead.
  • Depth resolve is unchanged on all platforms.

API Changes:

  • Added pc.platform.visionos (boolean).

Performance:

  • visionOS only: one extra blitFramebuffer (MSAA → scratch texture) plus one fullscreen quad draw per frame. Required because direct blits into the AVP XR FBO are broken; WEBGL_multisampled_render_to_texture is not available on AVP.
  • Other platforms: zero impact, gated on platform.visionos.

On Apple Vision Pro, gl.blitFramebuffer directly into the XRWebGLLayer
opaque framebuffer produces a small zoomed-in sub-region instead of
correct stereo content. On visionOS only, MSAA color is now resolved
into an engine-owned scratch texture first, then copied 1:1 into the XR
framebuffer via a single fullscreen quad draw — the rasterization path
that AVP renders correctly.

- Add pc.platform.visionos detection (Macintosh UA + maxTouchPoints > 0
  + no iPhone/iPad/iPod, since visionOS Safari spoofs a macOS UA)
- Add WebglXrMsaaCopy helper: scratch Texture/RenderTarget + fullscreen
  quad shader built via engine infrastructure (ShaderDefinitionUtils,
  device.scope, QuadRender-style draw)
- Gate the new path on platform.visionos in WebglRenderTarget.resolve —
  other XR platforms keep the direct-blit path with zero overhead

Fixes #7410

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a visionOS-specific workaround for WebXR MSAA resolves by avoiding direct gl.blitFramebuffer into the XR opaque framebuffer (which visionOS WebKit renders incorrectly) and instead resolving into an intermediate texture and copying via a fullscreen quad. It also exposes a new pc.platform.visionos flag for platform detection.

Changes:

  • Added pc.platform.visionos boolean detection for Apple Vision Pro / visionOS.
  • Introduced WebglXrMsaaCopy helper to resolve MSAA into a scratch texture and then draw a fullscreen quad into the XR framebuffer.
  • Updated WebglRenderTarget.resolve to route XR MSAA color resolves through the helper on visionOS only, preserving the existing direct-blit path elsewhere.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

File Description
src/platform/graphics/webgl/webgl-xr-msaa-copy.js New helper implementing MSAA resolve to scratch texture + fullscreen quad copy into XR framebuffer.
src/platform/graphics/webgl/webgl-render-target.js Routes XR MSAA color resolves through the new helper on platform.visionos.
src/platform/graphics/webgl/webgl-graphics-device.js Lazily instantiates/destroys the helper and exposes an internal resolve entry point.
src/core/platform.js Adds platform.visionos detection and exposes it on the platform namespace.
Comments suppressed due to low confidence (1)

src/platform/graphics/webgl/webgl-graphics-device.js:1120

  • The docstring mentions resolving MSAA color into the XR framebuffer “via two quad draws”, but the helper performs one fullscreen quad draw (plus a blit into a scratch texture). Please adjust the wording so it reflects the real steps (blit + single quad) and matches the helper’s implementation.
    /**
     * Resolve multisampled color into the WebXR session framebuffer via two textured quad draws
     * (horizontal SBS). Used on visionOS / Apple Vision Pro where direct `blitFramebuffer` into
     * the XR opaque framebuffer does not produce correct results.
     *

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/platform/graphics/webgl/webgl-xr-msaa-copy.js Outdated
Comment thread src/platform/graphics/webgl/webgl-render-target.js Outdated
Comment thread src/platform/graphics/webgl/webgl-graphics-device.js
Comment thread src/platform/graphics/webgl/webgl-xr-msaa-copy.js Outdated
@mvaligursky mvaligursky merged commit c3cd1f9 into main May 15, 2026
8 checks passed
@mvaligursky mvaligursky deleted the mv-fix-avp-msaa-xr-resolve branch May 15, 2026 12:50
Comment thread src/core/platform.js
*
* @type {boolean}
*/
visionos: visionos,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Gotta say - I'm not a fan of explanding the platform object further. This user agent sniffing technique is really scary (should the browser change it someday) - people's published app behavior can suddenly change/break.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah those are dirty.
but I need it internally .. I'll make it @ignore.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

making it non-public here #8765

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: graphics Graphics related issue area: xr XR related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WebXR: Apple Vision Pro rendering issues

3 participants