-
Notifications
You must be signed in to change notification settings - Fork 23.2k
Editorial review: Document WebXR visibilitymaskchange event #43975
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
base: main
Are you sure you want to change the base?
Changes from all commits
eb1fbd4
5ad0cc7
ceb3069
76e0bf5
77846cd
1918ed0
62cd79c
d23d990
5ebbe66
00ccaa2
d013105
efa2466
5c40871
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| --- | ||
| title: "XRSession: visibilitymaskchange event" | ||
| short-title: visibilitymaskchange | ||
| slug: Web/API/XRSession/visibilitymaskchange_event | ||
| page-type: web-api-event | ||
| status: | ||
| - experimental | ||
| browser-compat: api.XRSession.visibilitymaskchange_event | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SeeCompatTable}}{{SecureContext_Header}} | ||
|
|
||
| The **`visibilitymaskchange`** event is sent to an {{domxref("XRSession")}} when the portion of an {{domxref("XRView")}} visible to the user changes. | ||
|
|
||
| Note that the view is associated with a particular eye, and the part that is visible to the user is defined by a visibility mask. For more information see the {{domxref("XRVisibilityMaskChangeEvent")}} interface. | ||
|
|
||
| This enables performance improvements by allowing the browser to draw only the visible part of the updated view. | ||
|
|
||
| ## Syntax | ||
|
|
||
| Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property. | ||
|
|
||
| ```js-nolint | ||
| addEventListener("visibilitymaskchange", (event) => { }) | ||
|
|
||
| onvisibilitymaskchange = (event) => { } | ||
| ``` | ||
|
|
||
| ## Event type | ||
|
|
||
| An {{domxref("XRVisibilityMaskChangeEvent")}}. Inherits from {{domxref("Event")}}. | ||
|
|
||
| {{InheritanceDiagram("XRVisibilityMaskChangeEvent")}} | ||
|
|
||
| ## Event properties | ||
|
|
||
| _In addition to the properties listed below, properties from the parent interface, {{domxref("Event")}}, are available._ | ||
|
|
||
| - {{domxref("XRVisibilityMaskChangeEvent.eye", "eye")}} {{ReadOnlyInline}} | ||
| - : The eye the mask applies to. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.index", "index")}} {{ReadOnlyInline}} | ||
| - : The index of the current {{domxref("XRView")}} in the {{domxref("XRViewerPose.views")}} array. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.indices", "indices")}} {{ReadOnlyInline}} | ||
| - : An array of indices specifying the vertices in the `vertices` array that should be drawn to display the currently visible part of the scene displayed in the `XRView`. If this array is empty, the whole region of the `XRView` will be drawn. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.session", "session")}} {{ReadOnlyInline}} | ||
| - : The {{domxref("XRSession")}} to which the event refers. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.vertices", "vertices")}} {{ReadOnlyInline}} | ||
| - : An array of coordinates representing the vertices required to draw the entire scene displayed in the `XRView`. If this array is empty, the whole region of the `XRView` will be drawn. | ||
|
|
||
|
hamishwillee marked this conversation as resolved.
|
||
| ## Examples | ||
|
|
||
| ### Three.js example | ||
|
|
||
| This snippet shows how `visibilitymaskchange` might be used to draw only the visible portion of the `XRView` in a Three.js application. The new view must be drawn using the {{domxref("XRView.projectionMatrix")}} of the relevant `XRView` and a default {{domxref("XRRigidTransform")}}. | ||
|
|
||
| ```js | ||
| session.addEventListener("visibilitymaskchange", onVisibilityMaskChange); | ||
|
|
||
| function onVisibilityMaskChange(event) { | ||
| const geometry = new BufferGeometry(); | ||
| geometry.setIndex(new BufferAttribute(event.indices, 1)); | ||
| const vertices = new Float32Array((event.vertices.length / 2) * 3); | ||
| let x = 0, | ||
| y = 0; | ||
| while (x < event.vertices.length) { | ||
| vertices[y++] = event.vertices[x++]; | ||
| vertices[y++] = event.vertices[x++]; | ||
| vertices[y++] = -1; | ||
| } | ||
|
|
||
| geometry.setAttribute("position", new BufferAttribute(vertices, 3)); | ||
|
|
||
| const mask = event.eye === "left" ? leftEyeMask : rightEyeMask; | ||
| const matrix = cameras[event.eye === "left" ? 0 : 1].projectionMatrix; | ||
| mask.geometry = geometry; | ||
| mask.material = new ShaderMaterial({ | ||
| vertexShader: _visibility_mask_vertex, | ||
| fragmentShader: _visibility_mask_fragment, | ||
| uniforms: { | ||
| clipMatrix: { value: matrix }, | ||
| }, | ||
| }); | ||
|
|
||
| maskScene = new Scene(); | ||
| maskScene.add(leftEyeMask); | ||
| maskScene.add(rightEyeMask); | ||
| } | ||
| ``` | ||
|
|
||
| The code snippet is taken from [this fork of WebXRManager.js](https://github.com/cabanier/three.js/blob/78a3227d95fc29e001d8cd139504c643987430c5/src/renderers/webxr/WebXRManager.js). | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| --- | ||
| title: "XRView: index property" | ||
| short-title: index | ||
| slug: Web/API/XRView/index | ||
| page-type: web-api-instance-property | ||
| browser-compat: api.XRView.index | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The **`index`** read-only property of the {{domxref("XRView")}} interface indicates the index of the current `XRView` in the {{domxref("XRViewerPose.views")}} array. | ||
|
|
||
| ## Value | ||
|
|
||
| A number. | ||
|
|
||
| ## Examples | ||
|
|
||
|
chrisdavidmills marked this conversation as resolved.
|
||
| ### Basic usage | ||
|
|
||
| ```js | ||
| console.log(xrView.index); | ||
| ``` | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - {{domxref("XRViewerPose.views")}} | ||
| - {{domxref("XRFrame.getViewerPose()")}} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| --- | ||
| title: "XRVisibilityMaskChangeEvent: eye property" | ||
| short-title: eye | ||
| slug: Web/API/XRVisibilityMaskChangeEvent/eye | ||
| page-type: web-api-instance-property | ||
| browser-compat: api.XRVisibilityMaskChangeEvent.eye | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The **`eye`** read-only property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface indicates the eye the mask applies to. | ||
|
|
||
| ## Value | ||
|
|
||
| An emumerated value indicating which eye the mask applies to from the viewer's perspective. | ||
| This can be one of: | ||
|
|
||
| - `left` | ||
| - : The viewer's left eye. | ||
| - `right` | ||
| - : The viewer's right eye. | ||
| - `none` | ||
| - : A monoscopic view, or the view otherwise doesn't represent a particular eye's point-of-view. | ||
|
|
||
| ## Examples | ||
|
|
||
|
chrisdavidmills marked this conversation as resolved.
|
||
| ### Basic usage | ||
|
|
||
| This example indicates how you might check the `eye` value when the `visibilitymaskchange` event fires and then render a suitable display update depending on the result. | ||
|
|
||
| ```js | ||
| xrSession.addEventListener("visibilitymaskchange", (e) => { | ||
| if (e.eye === "left") { | ||
| // Render for left eye view | ||
| } else if (e.eye === "right") { | ||
| // Render for right eye view | ||
| } else { | ||
| // Render for neutral view | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - {{domxref("XRView.eye")}} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| --- | ||
| title: XRVisibilityMaskChangeEvent | ||
| slug: Web/API/XRVisibilityMaskChangeEvent | ||
| page-type: web-api-interface | ||
| browser-compat: api.XRVisibilityMaskChangeEvent | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The **`XRVisibilityMaskChangeEvent`** of the [WebXR Device API](/en-US/docs/Web/API/WebXR_Device_API) describes the portion of an {{domxref("XRView")}} visible to the user after the view has changed, for example by specifying the eye that the view is relevant to, and the vertices of a visibility mask that defines the visible part of the view. This enables performance improvements by allowing the browser to draw only the visible part of the updated view. | ||
|
|
||
| An `XRVisibilityMaskChangeEvent` object is made available as the event object of a {{domxref("XRSession.visibilitymaskchange_event", "visibilitymaskchange")}} event, fired each time the portion of the view displayed to the user changes to provide new information to update the view. | ||
|
|
||
| {{InheritanceDiagram}} | ||
|
|
||
| ## Constructor | ||
|
|
||
| - {{domxref("XRVisibilityMaskChangeEvent.XRVisibilityMaskChangeEvent", "XRVisibilityMaskChangeEvent()")}} | ||
| - : Creates and returns a new `XRVisibilityMaskChangeEvent` object. | ||
|
|
||
| ## Instance properties | ||
|
|
||
| _In addition to properties inherited from its parent interface, {{domxref("Event")}}, `XRVisibilityMaskChangeEvent` provides the following:_ | ||
|
|
||
| - {{domxref("XRVisibilityMaskChangeEvent.eye", "eye")}} {{ReadOnlyInline}} | ||
| - : The eye the mask applies to. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.index", "index")}} {{ReadOnlyInline}} | ||
| - : The index of the current {{domxref("XRView")}} in the {{domxref("XRViewerPose.views")}} array. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.indices", "indices")}} {{ReadOnlyInline}} | ||
| - : An array of values specifying the array positions of the vertices in the [vertices](#vertices) array that define the currently visible part of the scene displayed in the {{domxref("XRView")}}. If this array is empty, the whole region of the `XRView` will be drawn. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.session", "session")}} {{ReadOnlyInline}} | ||
| - : The {{domxref("XRSession")}} to which the event belongs. | ||
| - {{domxref("XRVisibilityMaskChangeEvent.vertices", "vertices")}} {{ReadOnlyInline}} | ||
| - : An array of coordinate values representing a visibility mask. If this array is empty, the whole region of the `XRView` will be drawn. | ||
|
|
||
| ## Instance methods | ||
|
|
||
| _While `XRSessionEvent` defines no methods, it inherits methods from its parent interface, {{domxref("Event")}}._ | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Three.js example | ||
|
|
||
| This snippet shows how `visibilitymaskchange` might be used to draw only the visible portion of the `XRView` in a Three.js application. The new view must be drawn using the {{domxref("XRView.projectionMatrix")}} of the relevant `XRView` and a default {{domxref("XRRigidTransform")}}. | ||
|
|
||
| ```js | ||
| session.addEventListener("visibilitymaskchange", onVisibilityMaskChange); | ||
|
|
||
| function onVisibilityMaskChange(event) { | ||
| const geometry = new BufferGeometry(); | ||
| geometry.setIndex(new BufferAttribute(event.indices, 1)); | ||
| const vertices = new Float32Array((event.vertices.length / 2) * 3); | ||
| let x = 0, | ||
| y = 0; | ||
| while (x < event.vertices.length) { | ||
| vertices[y++] = event.vertices[x++]; | ||
| vertices[y++] = event.vertices[x++]; | ||
| vertices[y++] = -1; | ||
| } | ||
|
Comment on lines
+49
to
+59
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could probably use some words. IN particular this looks like it is creating a three dimensional structure from the 2D point information in event.vertices - but I am not sure why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per my other comment you need to iterate through the indices array. Not just increment your own indices. @toji can help me out here, there MAY be a WebGL or other structure you can basically just pass them into
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is using Three.js, which (as far as I can tell) requires the With raw WebGL there's no specific requirement for the number of elements in an attribute, as the developer interprets it in the shaders. So there are scenarios where you could pass the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, just realized I probably read Alex's question wrong.
|
||
|
|
||
| geometry.setAttribute("position", new BufferAttribute(vertices, 3)); | ||
|
|
||
| const mask = event.eye === "left" ? leftEyeMask : rightEyeMask; | ||
| const matrix = cameras[event.eye === "left" ? 0 : 1].projectionMatrix; | ||
| mask.geometry = geometry; | ||
| mask.material = new ShaderMaterial({ | ||
| vertexShader: _visibility_mask_vertex, | ||
| fragmentShader: _visibility_mask_fragment, | ||
| uniforms: { | ||
| clipMatrix: { value: matrix }, | ||
| }, | ||
| }); | ||
|
|
||
| maskScene = new Scene(); | ||
| maskScene.add(leftEyeMask); | ||
| maskScene.add(rightEyeMask); | ||
| } | ||
| ``` | ||
|
|
||
| The code snippet is taken from [this fork of WebXRManager.js](https://github.com/cabanier/three.js/blob/78a3227d95fc29e001d8cd139504c643987430c5/src/renderers/webxr/WebXRManager.js). | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --- | ||
| title: "XRVisibilityMaskChangeEvent: index property" | ||
| short-title: index | ||
| slug: Web/API/XRVisibilityMaskChangeEvent/index | ||
| page-type: web-api-instance-property | ||
| browser-compat: api.XRVisibilityMaskChangeEvent.index | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The **`index`** read-only property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface indicates the index of the current {{domxref("XRView")}} in the {{domxref("XRViewerPose.views")}} array. | ||
|
|
||
| For a stereo view, there will be two views in the array. The `index` property allows you to identify the correct view to re-render, rather than having to re-render all views unnecessarily. | ||
|
|
||
| ## Value | ||
|
|
||
| A number. | ||
|
|
||
| ## Examples | ||
|
|
||
| This example indicates how you might render a display update for a particular {{domxref("XRView")}} by querying the `index` value of the event object when a `visibilitymaskchange` event is fired. | ||
|
|
||
| ```js | ||
| xrSession.addEventListener("visibilitymaskchange", (e) => { | ||
| renderNewView(e.index); | ||
| }); | ||
| ``` | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - {{domxref("XRViewerPose.views")}} | ||
| - {{domxref("XRFrame.getViewerPose()")}} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| title: "XRVisibilityMaskChangeEvent: indices property" | ||
| short-title: indices | ||
| slug: Web/API/XRVisibilityMaskChangeEvent/indices | ||
| page-type: web-api-instance-property | ||
| browser-compat: api.XRVisibilityMaskChangeEvent.indices | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The **`indices`** read-only property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface is an array of values specifying the array positions of the vertices in the {{domxref("XRVisibilityMaskChangeEvent.vertices", "vertices")}} array that define the currently visible part of the scene displayed in the {{domxref("XRView")}}. If this array is empty, the whole region of the `XRView` will be drawn. | ||
|
|
||
| ## Value | ||
|
|
||
| A {{domxref("Uint32Array")}}. | ||
|
|
||
| ## Examples | ||
|
|
||
| See the main [`XRVisibilityMaskChangeEvent`](/en-US/docs/Web/API/XRVisibilityMaskChangeEvent) page for an example. | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - {{domxref("XRVisibilityMaskChangeEvent.vertices")}} |
Uh oh!
There was an error while loading. Please reload this page.