Skip to content
immersive-web  /   webxr-samples  /  
Clear Command Palette
Tip: Type # to search pull requests
Type ? for help and tips
Tip: Type # to search issues
Type ? for help and tips
Tip: Type # to search discussions
Type ? for help and tips
Tip: Type ! to search projects
Type ? for help and tips
Tip: Type @ to search teams
Type ? for help and tips
Tip: Type @ to search people and organizations
Type ? for help and tips
Tip: Type > to activate command mode
Type ? for help and tips
Tip: Go to your accessibility settings to change your keyboard shortcuts
Type ? for help and tips
Tip: Type author:@me to search your content
Type ? for help and tips
Tip: Type is:pr to filter to pull requests
Type ? for help and tips
Tip: Type is:issue to filter to issues
Type ? for help and tips
Tip: Type is:project to filter to projects
Type ? for help and tips
Tip: Type is:open to filter to open content
Type ? for help and tips
We’ve encountered an error and some results aren't available at this time. Type a new search or try again later.
No results matched your search
Search for issues and pull requests # Search for issues, pull requests, discussions, and projects # Search for organizations, repositories, and users @ Search for projects ! Search for files / Activate command mode > Search your issues, pull requests, and discussions # author:@me Search your issues, pull requests, and discussions # author:@me Filter to pull requests # is:pr Filter to issues # is:issue Filter to discussions # is:discussion Filter to projects # is:project Filter to open issues, pull requests, and discussions # is:open
  • Watch 100


    Get push notifications on iOS or Android.
Open in Open in a new tab
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
Cannot retrieve contributors at this time
<!DOCTYPE html>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='chrome=1'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<meta name='mobile-web-app-capable' content='yes'>
<meta name='apple-mobile-web-app-capable' content='yes'>
<meta name='twitter:card' content='summary'>
<meta name='twitter:title' content='WebXR Samples'>
<meta name='twitter:description' content='Sample WebXR pages for testing and reference'>
<link rel='icon' type='image/png' sizes='32x32' href='../favicon-32x32.png'>
<link rel='icon' type='image/png' sizes='96x96' href='../favicon-96x96.png'>
<link rel='stylesheet' href='../css/stylesheet.css'>
<link rel='stylesheet' href='../css/pygment_trac.css'>
article {
position: relative;
padding: 0.5em;
background-color: rgba(255, 255, 255, 0.90);
margin-bottom: 1em;
border-radius: 3px;
article h3 {
font-size: 1.0em;
margin-top: 0px;
margin-bottom: 0px;
article h3::before {
display: inline-block;
content: attr(data-index) ' - ';
font-weight: bold;
white-space: nowrap;
margin-right: 0.2em;
article h4 {
position: absolute;
right: 0.5em;
top: 0.5em;
margin-top: 0px;
margin-bottom: 0px;
article p {
margin: 0.5em;
article .links {
margin-left: 0.5em;
margin-right: 0.5em;
article a {
display: inline-block;
article a:not(:first-child)::before {
display: inline-block;
content: '•';
font-weight: bold;
white-space: nowrap;
margin-left: 0.5em;
margin-right: 0.5em;
.github-link {
font-size: 0.8em;
.wordmark img {
width: 70%;
<!--[if lt IE 9]>
<script src=''></script>
<title>WebXR - Test Pages</title>
<div class='container' id='container'>
<header class='header'>
<div id='nav'>
<a href='../'>Samples</a>
<a href='../layers-samples/'>Layers Samples</a>
<a href='../proposals/'>Proposals</a>
<a href='./' class='selected'>Test Pages</a>
<a href='../report/'>Report</a>
<a href='' class='wordmark'>
<img src='../media/logo/webxr-logo.svg' alt='WebXR Logo'/>
<h2 class='tagline'>Test Pages</h2>
<main class='main' id='main'>
<p>These pages are useful for testing various aspects of WebXR
implementations, but aren't as well commented or straightforward as
the sample pages.<br/>
let pages = [
{ title: 'Cube Sea', category: 'Cube Sea',
path: 'cube-sea.html',
description: 'All hail the cube sea! Not very interesting to look at, but it\'s fantastic for testing!' },
{ title: 'Pointer Painter', category: 'Input',
path: 'pointer-painter.html',
description: 'Leaves behind a trail of pointers and cursors on select events.' },
{ title: 'User Agent Prompts', category: 'User Agent Behavior',
path: 'permission-request.html',
description: 'Tests various prompts (PWA install, permission requests, notifications) from within XR.' },
{ title: 'Offscreen Canvas', category: 'Alternate WebGL Modes',
path: 'offscreen-canvas.html',
description: 'Tests use of an OffscreenCanvas with XR.' },
{ title: 'Sponza', category: 'Lots-o-Polys',
path: 'sponza.html',
description: 'Loads a larger scene than other samples for performance testing. (Warning: Can be slow on mobile devices!)' },
{ title: 'Composed Views', category: 'We Like Matrix Math',
path: 'composed-views.html',
description: 'Tests a scenario where views are composed from a combination of viewer and local-floor space.' },
{ title: 'Reference Space Invert', category: 'We Hate Matrix Math',
path: 'ref-space-invert.html',
description: 'Tests creating an offset reference space with the viewer pose, which should cancel out the pose and report the viewer at the origin.' },
{ title: 'Interrupted AR', category: 'Exceptions!',
path: 'interrupted-ar.html',
description: 'Tests what happens when an exception is thrown in promise resolve of an `immersive-ar` session request.' },
{ title: 'Sparse Frames', category: 'M_ss_ng Fr_m_s',
path: 'sparse-frames.html',
description: 'Tests what happens the framebuffer is not populated every frame.' },
{ title: 'WebGL 2.0 Multisampling', category: 'Artisinally crafted pixels',
path: 'webgl2-multisample.html',
description: 'Tests that multisample renderbuffers are usable with XRWebGLLayer.' },
let mainElement = document.getElementById("main");
// Append an element for every item in the pages list.
for (var i = 0; i < pages.length; ++i) {
var page = pages[i];
let article = document.createElement('article');
let title = document.createElement('h3');
title.setAttribute('data-index', i + 1);
let titleLink = document.createElement('a');
titleLink.href = page.path;
titleLink.textContent = page.title;
let category = document.createElement('h4');
category.textContent = page.category;
let description = document.createElement('p');
description.textContent = page.description;
let links = document.createElement('div');
let sourceLink = document.createElement('a');
sourceLink.href = '' + page.path;
sourceLink.textContent = 'Source';
if (!page.noPolyfill) {
let polyfillLink = document.createElement('a');
polyfillLink.href = page.path + '?usePolyfill=0';
polyfillLink.textContent = 'Run Without Polyfill';
<h3><a class='github-link' href=''>View source on GitHub</a></h3>
<footer class='footer'>