View a glTF model in AR on Android without leaving your browser

A big part of why we built glTF™ is to make it easy to serve 3D models to websites across the Internet. What better way to demonstrate this than to hook in to other web standards? I work on the Chrome XR team and we are proud to announce the addition of support for Augmented Reality (AR) to the WebXR API in Chrome 81, which has now rolled out to the world.

However, using WebXR still requires using WebGL™, which is a low-level API. The other project I work on facilitates high quality rendering of 3D models and abstracts both of these APIs: it is an open source web component called <model-viewer>. Now a single line of HTML will give your website an interactive, accessible 3D experience, including AR placement on both Android and iOS.

<model-viewer
    src="../assets/Chair.glb"
    ios-src="../assets/Chair.usdz"
    poster="../assets/ChairPoster.png"
    camera-orbit="1.2195rad 1.362rad auto"
    shadow-intensity="1"
    ar
    ar-modes="webxr scene-viewer quick-look fallback"
    camera-controls
    alt="3D model of a chair with footrest"
>

Copyright (c) 2020 Shopify, Inc.


The AR modes I have specified above choose an in-browser AR experience if available, or else launch a native application: either SceneViewer on Android or QuickLook on iOS. Bringing AR into the browser instead of relying on a native app is key to leveraging the power of the web to enhance your AR experiences. Now you can use JavaScript to create any kind of custom interaction you want in AR.

However, <model-viewer> focuses on making customization even easier than adding script, which makes us especially excited about the next feature coming to WebXR in Chrome: DOM Overlay. This lets your HTML and CSS flow right into your AR experience:

<style>
    /* This keeps child nodes hidden while the element loads */
    :not(:defined) > * {
      display: none;
    }
    .ar-button {
      background-image: url(../assets/ic_view_in_ar_new_googblue_48dp.png);
      background-repeat: no-repeat;
      background-size: 20px 20px;
      background-position: 12px 50%;
      background-color: #fff;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      bottom: 16px;
      padding: 0px 16px 0px 40px;
      font-family: Roboto Regular, Helvetica Neue, sans-serif;
      font-size: 14px;
      color:#4285f4;
      height: 36px;
      line-height: 36px;
      border-radius: 18px;
      border: 1px solid #DADCE0;
    }
    .ar-button:active {
      background-color: #E8EAED;
    }
    .ar-button:focus {
      outline: none;
    }
    .ar-button:focus-visible {
      outline: 1px solid #4285f4;
    }
    .hotspot {
      position: relative;
      background: #ddd;
      border-radius: 32px;
      box-sizing: border-box;
      border: 0;
      --min-hotspot-opacity: 0.5;
      width: 24px;
      height: 24px;
      padding: 8px;
      cursor: pointer;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
    }
    .hotspot:focus {
      border: 4px solid rgb(0, 128, 200);
      width: 32px;
      height: 32px;
      outline: none;
    }
    .hotspot > * {
      transform: translateY(-50%);
      opacity: 1;
    }
    .hotspot:not([data-visible]) > * {
      pointer-events: none;
      opacity: 0;
      transform: translateY(calc(-50% + 4px));
      transition: transform 0.3s, opacity 0.3s;
    }
    .info {
      display: block;
      position: absolute;
      font-family: Futura, Helvetica Neue, sans-serif;
      color: rgba(0, 0, 0, 0.8);
      font-weight: 700;
      font-size: 18px;
      max-width: 128px;
      padding: 0.5em 1em;
      background: #ddd;
      border-radius: 4px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
      left: calc(100% + 1em);
      top: 50%;
    }
    
</style>
<model-viewer
    src="../assets/Mixer.glb"
    ios-src="../assets/Mixer.usdz"
    poster="../assets/MixerPoster.png"
    camera-orbit="0.9677rad 1.2427rad auto"
    shadow-intensity="1"
    ar
    ar-modes="webxr scene-viewer quick-look fallback"
    camera-controls
    alt="3D model of a countertop mixer"
>
    <button slot="ar-button" class="ar-button">View in your space</button>
    <button
        slot="hotspot-1"
        class="hotspot"
        data-position="0.009m 0.14m 0.02m"
        data-normal="0.77m 0.64m -0.08m"
        data-visibility-attribute="visible"
    >
        <span class="info">Beater</span>
    </button>
    <button
        slot="hotspot-2"
        class="hotspot"
        data-position="0.03m 0.132m 0.148m"
        data-normal="0.33m 0.13m 0.93m"
        data-visibility-attribute="visible"
    >
        <span class="info">Bowl</span>
    </button>
    <button
        slot="hotspot-3"
        class="hotspot"
        data-position="0m 0.258m -0.142m"
        data-normal="0m 0.26m -0.97m"
        data-visibility-attribute="visible"
    >
        <span class="info">Speed</span>
    </button>
    <button
        slot="hotspot-4"
        class="hotspot"
        data-position="0.004m 0.270m 0.102m"
        data-normal="0.29m 0.96m 0m"
        data-visibility-attribute="visible"
    >
        <span class="info">Accessories</span>
    </button>
    <button
        slot="hotspot-5"
        class="hotspot"
        data-position="-0.056m 0.188m -0.093m"
        data-normal="-1m 0m 0m"
        data-visibility-attribute="visible"
    >
        <span class="info">Hinge</span>
    </button>
</model-viewer>

Copyright (c) 2020 Shopify, Inc.


If you look at this page in Chrome Beta on an AR-capable Android device you can see the annotations in AR as well.

The standardization of Physically Based Rendering (PBR) in glTF was key to enabling <model-viewer>, as it allowed us to create a high-quality renderer without detailed options to help individual models render correctly; it Just Works. As such, glTF is our required input format. You can still bring your own lighting by specifying an environment image , and with the power of PBR you can rest assured that the model will look realistic in any environment you supply.

As a member of the Khronos® glTF working group, it is my job to ensure that our rendering is as accurate and performant as possible and to keep up with the evolving extensions. The Three.js library is the foundation of <model-viewer> and as such we actively upstream rendering improvements to ensure the rest of the JavaScript community also has access to first-class glTF rendering for their custom use cases that <model-viewer> cannot fulfil.

Making accelerated 3D and AR in your browser this accessible is possible by leveraging standards from multiple standardization bodies. These include Khronos that has deep 3D expertise and develops WebGL and glTF, and the World Wide Web Consortium (W3C) that develops many key Web standards including WebXR. Both organizations are committed to open, royalty-free standards – and are cooperating ever more closely to ensure their standards work together seamlessly for the good of the industry.

Get started with AR today; all you need is a glTF model and one line of HTML. And please let your other browser vendors know that customizable AR matters to you: once WebXR is broadly supported, any website can deliver a complete AR experience across devices and browsers.

Authored by

Comments

 

Khronos® and Vulkan® are registered trademarks, and ANARI™, WebGL™, glTF™, NNEF™, OpenVX™, SPIR™, SPIR-V™, SYCL™, OpenVG™ and 3D Commerce™ are trademarks of The Khronos Group Inc. OpenXR™ is a trademark owned by The Khronos Group Inc. and is registered as a trademark in China, the European Union, Japan and the United Kingdom. OpenCL™ is a trademark of Apple Inc. and OpenGL® is a registered trademark and the OpenGL ES™ and OpenGL SC™ logos are trademarks of Hewlett Packard Enterprise used under license by Khronos. All other product names, trademarks, and/or company names are used solely for identification and belong to their respective owners.
devilish