Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions files/en-us/web/api/xrsession/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ _The following events are delivered to `XRSession` objects._
- : An event of type {{domxref("XRInputSourceEvent")}} which is sent to the `XRSession` when the user initially squeezes a squeezable controller. This may be, for example, a trigger which is used to represent grabbing objects, or might represent actual squeezing when wearing a haptic glove. Also available through the `onsqueezestart` event handler property.
- {{domxref("XRSession.visibilitychange_event", "visibilitychange")}} {{Experimental_Inline}}
- : An {{domxref("XRSessionEvent")}} which is sent to the session when its visibility state as indicated by the {{domxref("XRSession.visibilityState", "visibilityState")}} changes. Also available through the `onvisibilitychange` event handler property.
- {{domxref("XRSession.visibilitymaskchange_event", "visibilitymaskchange")}} {{Experimental_Inline}}
- : An {{domxref("XRVisibilityMaskChangeEvent")}} which is sent to the session when the portion of the {{domxref("XRView")}} visible to the user changes, enabling performance improvements by allowing the browser to draw only the visible part of the updated view. Also available through the `onvisibilitymaskchange` event handler property.

## Example

Expand Down
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}}
2 changes: 2 additions & 0 deletions files/en-us/web/api/xrview/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ The [WebXR Device API](/en-US/docs/Web/API/WebXR_Device_API)'s **`XRView`** inte
- : Which of the two eyes (`left`) or (`right`) for which this `XRView` represents the perspective. This value is used to ensure that any content which is pre-rendered for presenting to a specific eye is distributed or positioned correctly. The value can also be `none` if the `XRView` is presenting monoscopic data (such as a 2D image, a fullscreen view of text, or a close-up view of something that doesn't need to appear in 3D).
- {{domxref("XRView.isFirstPersonObserver", "isFirstPersonObserver")}} {{ReadOnlyInline}} {{Experimental_Inline}}
- : Returns a boolean indicating if the `XRView` is a first-person observer view.
- {{domxref("XRView.index", "index")}} {{ReadOnlyInline}} {{Experimental_Inline}}
- : Returns a number specifying the index of the current `XRView` in the {{domxref("XRViewerPose.views")}} array.
- {{domxref("XRView.projectionMatrix", "projectionMatrix")}} {{ReadOnlyInline}} {{Experimental_Inline}}
- : The projection matrix that will transform the scene to appear correctly given the point-of-view indicated by `eye`. This matrix should be used directly in order to avoid presentation distortions that may lead to potentially serious user discomfort.
- {{domxref("XRView.recommendedViewportScale", "recommendedViewportScale")}} {{ReadOnlyInline}} {{Experimental_Inline}}
Expand Down
34 changes: 34 additions & 0 deletions files/en-us/web/api/xrview/index/index.md
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 files/en-us/web/api/xrvisibilitymaskchangeevent/eye/index.md
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")}}
88 changes: 88 additions & 0 deletions files/en-us/web/api/xrvisibilitymaskchangeevent/index.md
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 files/en-us/web/api/xrvisibilitymaskchangeevent/index/index.md
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()")}}
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")}}
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) {
Copy link
Copy Markdown

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 userRequestsSessionEnd and clear it in the block as well?

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.

That's a fair comment. I've updated the variable name throughout to userRequestsSessionEnd in my next commit.

e.session.end();
} else {
renderNewView(e.index, e.eye, e.indices, e.vertices);
}
});
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}
Loading