-
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
Open
chrisdavidmills
wants to merge
2
commits into
mdn:main
Choose a base branch
from
chrisdavidmills:xrsession-visibilitymaskchange-event
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
files/en-us/web/api/xrsession/visibilitymaskchange_event/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| --- | ||
| 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 — that is, the portion not hidden by the mask. This enables performance improvements by allowing the browser to draw only the visible part of the updated view. The required information to draw the update is contained in the {{domxref("XRVisibilityMaskChangeEvent")}} event object. | ||
|
|
||
| ## 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. | ||
|
|
||
| ## 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}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| --- | ||
| 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 read-only **`index`** property of the {{domxref("XRView")}} interface indicates the index of the current `XRView` in the {{domxref("XRViewerPose.views")}} array. | ||
|
|
||
| ## Value | ||
|
|
||
| A number. | ||
|
|
||
| ## Examples | ||
|
|
||
| ```js | ||
| console.log(xrView.index); | ||
| ``` | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
|
|
||
| ## See also | ||
|
|
||
| - {{domxref("XRViewerPose.views")}} | ||
| - {{domxref("XRFrame.getViewerPose()")}} |
50 changes: 50 additions & 0 deletions
50
files/en-us/web/api/xrvisibilitymaskchangeevent/eye/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| --- | ||
| 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 read-only **`eye`** property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface indicates the eye the mask applies to. | ||
|
|
||
| ## Value | ||
|
|
||
| An emumerated value indicating which eye the mask applies to, which can be one of: | ||
|
|
||
| - `left` | ||
| - : The {{domxref("XRView")}} represents the point-of-view of the viewer's left eye. | ||
| - `right` | ||
| - : The view represents the viewer's right eye. | ||
| - `none` | ||
| - : The `XRView` describes a monoscopic view, or the view otherwise doesn't represent a particular eye's point-of-view. | ||
|
|
||
| ## Examples | ||
|
|
||
| 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")}} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 (that is, the portion not hidden by the mask) after the view has changed. 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 when the portion of the view displayed to the user changes. | ||
|
|
||
| {{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 indices specifying the vertices in the [`vertices`](#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 belongs. | ||
| - {{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. | ||
|
|
||
| ## 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; | ||
| } | ||
|
|
||
| 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}} |
38 changes: 38 additions & 0 deletions
38
files/en-us/web/api/xrvisibilitymaskchangeevent/index/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| --- | ||
| 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 read-only **`index`** property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface indicates the index of the current {{domxref("XRView")}} in the {{domxref("XRViewerPose.views")}} array. | ||
|
|
||
| ## 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()")}} |
31 changes: 31 additions & 0 deletions
31
files/en-us/web/api/xrvisibilitymaskchangeevent/indices/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 read-only **`indices`** property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface is an array of indices specifying the vertices in the {{domxref("XRVisibilityMaskChangeEvent.vertices", "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. | ||
|
|
||
| ## 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")}} |
39 changes: 39 additions & 0 deletions
39
files/en-us/web/api/xrvisibilitymaskchangeevent/session/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| --- | ||
| title: "XRVisibilityMaskChangeEvent: session property" | ||
| short-title: session | ||
| slug: Web/API/XRVisibilityMaskChangeEvent/session | ||
| page-type: web-api-instance-property | ||
| browser-compat: api.XRVisibilityMaskChangeEvent.session | ||
| --- | ||
|
|
||
| {{APIRef("WebXR Device API")}}{{SecureContext_Header}} | ||
|
|
||
| The read-only **`session`** property of the {{domxref("XRVisibilityMaskChangeEvent")}} interface indicates the {{domxref("XRSession")}} to which the event belongs. | ||
|
|
||
| ## Value | ||
|
|
||
| An {{domxref("XRSession")}} object indicating which WebXR session the event belongs to. | ||
|
|
||
| ## Examples | ||
|
|
||
| This example indicates how you might check a custom `userSessionEnded` value when the `visibilitymaskchange` event fires to see whether the user has manually selected an option to end the XR session. If so, you can access the `XRSession` via the `session` property and end the session using {{domxref("XRSession.end()")}}. | ||
|
|
||
| If the user has not selected this option, you could run some kind of function to render the new view based on the other values available in the `XRVisibilityMaskChangeEvent` object. | ||
|
|
||
| ```js | ||
| xrSession.addEventListener("visibilitymaskchange", (e) => { | ||
| if (userSessionEnded) { | ||
| e.session.end(); | ||
| } else { | ||
| renderNewView(e.index, e.eye, e.indices, e.vertices); | ||
| } | ||
| }); | ||
| ``` | ||
|
|
||
| ## Specifications | ||
|
|
||
| {{Specifications}} | ||
|
|
||
| ## Browser compatibility | ||
|
|
||
| {{Compat}} | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
NIT: This is a little confusing, I thought it was tracking some variable that the session had already ended at first glance/read through. maybe
userRequestsSessionEndand clear it in the block as well?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.
That's a fair comment. I've updated the variable name throughout to
userRequestsSessionEndin my next commit.