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

XR Viewer 2.0 -- WebXR immersive-ar mode still alpha-blends camera input into compositor, resulting in "heavy flickering" for scenes intended to be opaque #193

Open
AnachronicNomad opened this issue Jan 11, 2022 · 1 comment

Comments

@AnachronicNomad
Copy link

Issue also available at mozilla-mobile/firefox-ios located here: mozilla-mobile/firefox-ios#9752

Steps to reproduce

Download XR Viewer 2.0 for iOS and navigate to https://www.rn9peechnuxclbyp.xyz/#ferns-castle. This is a test domain my team has been using. Attempt to "Enter AR" with highlight white button at bottom. Pan screen around your surroundings to observe strong flickering from the compositor not blending what should be opaque. Screen-recording attachment link included under Actual Behavior header.

The implementation is borrowed as follows from https://developers.google.com/ar/develop/webxr/hello-webxr#render_the_scene, in addition to following the W3C Specification document for the Web AR module for WebXR at https://www.w3.org/TR/webxr-ar-module-1/#xr-compositor-behaviors, where in the note it is stated that:

NOTE: When using a device that performs alpha-blend environment blending, use of a baseLayer with no alpha channel will result in the real-world environment being completely obscured. It should be assumed that this is intentional on the part of developer, and the user agent may wish to suspend compositing of real-world environment as an optimization in such cases.

Implementation proper, where the base XRWebGLLayer has been set to not have an alpha channel:

button.onclick = async function () {

				if ( currentSession === null ) {

					camera_ref.position.z = 1.78

					// WebXR's requestReferenceSpace only works if the corresponding feature
					// was requested at session creation time. For simplicity, just ask for
					// the interesting ones as optional features, but be aware that the
					// requestReferenceSpace call will fail if it turns out to be unavailable.
					// ('local' is always available for immersive sessions and doesn't need to
					// be requested separately.)

					camera_ref.matrixAutoUpdate = false;

					const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking' ] };
					const session = navigator.xr.requestSession( session_type, sessionInit ).then( onSessionStarted );

					const gl = canvas.getContext("webgl2", {xrCompatible: true});

                                        // !!! Here's the important bit, where setting the alpha channel of the XRWebGLLayer base layer should 
                                        // occlude or not composite the camera input.  
					session.updateRenderState({
						baseLayer: new XRWebGLLayer(session, gl, {
								alpha: false,
								antialias: true,
								depth: false,
								framebufferScaleFactor: 1.0,
								ignoreDepthValues: true,
								stencil: false
						})
				});


					const referenceSpace = await session.requestReferenceSpace('local');

					// Create a render loop that allows us to draw on the AR view.
					const onXRFrame = (time, frame) => {
						// Queue up the next draw request.
						session.requestAnimationFrame(onXRFrame);
					
						// Bind the graphics framebuffer to the baseLayer's framebuffer
						gl.bindFramebuffer(gl.FRAMEBUFFER, session.renderState.baseLayer.framebuffer)
					
						// Retrieve the pose of the device.
						// XRFrame.getViewerPose can return null while the session attempts to establish tracking.
						const pose = frame.getViewerPose(referenceSpace);
						if (pose) {
						// In mobile AR, we only have one view.
						const view = pose.views[0];
					
						const viewport = session.renderState.baseLayer.getViewport(view);
						renderer.setSize(viewport.width, viewport.height)
					
						// Use the view's transform matrix and projection matrix to configure the THREE.camera.
						camera.matrix.fromArray(view.transform.matrix)
						camera.projectionMatrix.fromArray(view.projectionMatrix);
						camera.updateMatrixWorld(true);
					
						// Render the scene with THREE.WebGLRenderer.
						renderer.render(scene, camera)
						}
					}
					session.requestAnimationFrame(onXRFrame);
  
				} else {

					currentSession.end();

				}

			};

Expected behavior

The rendered scene should remain opaque, with camera feedback remaining invisible behind ThreeJS scene background color. Compare with using Chrome 97.0.4692.70 on Android 11, navigating to the same webpage.

All things considered I really only just need a monoscopic immersive view for immediate benchmarks. While it would be great to include blended/augmented camera information at a much later date, our immediate goals require a cross-platform, opaque, spatially-aware AR/VR monoscopic view. I didn't know if I should post this issue into https://github.com/immersive-web/webxr-ar-module or not.

Any insight on if this is not a bug, I just did it wrong, is very very welcome. I could not for the life of me figure out how to get about:config to open up to enable immersive-ar mode on either of Firefox for iOS or for Android to confirm specific versions which fail. Can only confirm that Chrome on Android exhibits the desired behavior, but it did this without me having set any base layer originally, so I don't know if the scene background just resulted in a perfect opaque WebGL layer in their implementation? Am fully lost.

Actual behavior

Alpha blending still occurs in compositor, with camera input overriding artificial scene construction.

Screen recording available here: https://youtu.be/guBImgk4DcM

Device & build information

Reproduced on this device, but was reproduced on Mozilla XR Viewer 2.0 on all iPhone 12 models.

  • Device: iPad Pro (12.9 in) (4th generation), software version 14.7.1
  • Build version: Mozilla XR Viewer Version 2.0 (280)

Notes

Attachments:

source and video attachments provided further up in "*-behavior" portions of bug report.

┆Issue is synchronized with this Jira Task

@AnachronicNomad
Copy link
Author

It turns out that creating a new Renderer and animation with a separate baseLayer was conflicting with the Three.js renderer object I was using, which creates its own XRWebGLLayer with an unspecified alpha layer. Continuing search to see if setting alpha and blend settings in Three.js (v0.136.0) renderer improves situation.

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

No branches or pull requests

1 participant