Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Create Web AR Experiences

Fivos Doganis
fivos.doganis@gmail.com

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Focus on standalone AR

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Setup: testing on your mobile

  • Check that your smartphone can read QR codes
  • iOS  
    • default Camera app
  • Android  
    • use Google Chrome + scan button
    • or install a trustworthy QR code scanning app like Trend Micro
  • Other 100% web based alternatives
    • webqr.com
    • qrcodescan.in
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Native AR

ARCore  
ARKit  

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

ModelViewer

Check if your device supports Native AR

  • on your mobile, open

https://modelviewer.dev/

  • click on the AR icon
  • see the astronaut in AR 🎉
    • uses SceneViewer (Android)
    • or QuickLook (iOS)
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Android  

http://storage.googleapis.com/ar-answers-in-search-models/static/mandalorian/grogu/grogu.glb

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

iOS  

http://storage.googleapis.com/ar-answers-in-search-models/static/mandalorian/grogu/grogu.usdz

  • USDZ file format
  • Native AR QuickLook Preview
    • uses Apple's ARKit
    • realistic lighting and occlusions
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

More examples

https://sketchfab.com/

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebAR

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Why use the Web for AR?

  • mobile experiences
  • open technologies
    • cross-platform
    • non-propietary (unlike Unity or Unreal)
    • free
    • distribute by sharing URLs : no installation, no app store
  • easy integration with many existing Web APIs
    • anchors the the web to the real world
    • advanced interactions
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Reminder: WebGL Stack

WebXR ↔️ WebGL / WebGPU
OpenXR / Reality Kit / ARKit ↔️ OpenGL / DirectX / Metal
HMD + controllers ↔️ GPU + screen

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebGL architecture: software stack

  • Code: HTML + CSS + JS
    • JS code inside the web page makes WebGL API calls
  • Browser:
    • browser interprets JS code (using JS Engine)
    • turns WebGL calls into OpenGL calls (binding)
  • OS + Driver: converts OpenGL calls to
    • DirectX calls on Windows, Metal on Apple (using ANGLE)
    • OpenGL or OpenGL ES calls on other OSes
  • CPU + GPU: run the hardware accelerated code!
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Binding example: from JS to C++

gl.drawElements(primitiveType, count, indexType, offset);
JSValue JSCanvasRenderingContext3D::glDrawElements(JSC::ExecState* exec, JSC::ArgList const& args)
{
    unsigned mode = args.at(0).toInt32(exec);
    unsigned type = args.at(1).toInt32(exec);

    unsigned int count = 0;

    // If the third param is not an object, it is a number, which is the count.
    // In this case if there is a 4th param, it is the offset. If there is no
    // 4th param, the offset is 0
    if (!args.at(2).isObject()) {
        count = args.at(2).toInt32(exec);
        unsigned int offset = (args.size() > 3) ? args.at(3).toInt32(exec) : 0;
        impl()->glDrawElements(mode, count, type, (void*) offset);
    } else {
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Hybrid Apps

Native + Web

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Hybrid Apps

  • Some feature are not available via JS in the standard browser
    • e.g.: no LiDAR access
  • Web Plugins are forbidden
    • security, installation and update issues
  • Idea: reuse existing web browser components
    • native low-level code (C++, Java, Kotlin, Objective-C, Swift)
    • create new APIs in JS, which call the native code
  • issues with non-standard APIs: if we create our own APIs the code might not be portable
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Architecture

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Why?

  • Pros
    • expose missing APIs in JS: often the only solution!
    • speed: call native code, faster than pure JS
    • portable code: app logic written in JS
  • Cons
    • still slower than a 100% native app
    • wasted performance when converting between JS and native
    • lowest common denominator to satisfy most platforms
    • non-native look and UI (not very important for immersive apps)
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Setup

How to run the examples locally

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Full setup using NPM

sudo apt install nodejs
curl -L https://npmjs.org/install.sh | sudo sh 

See below 👇

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Bundlers

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Automatic installation

THREE.js + WebXR with "batteries included" 🎉

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

THREE Vite WebXR boilerplate

Preconfigured environment (allows to test all official examples)

https://github.com/fdoganis/three_vite_xr ⭐

git clone https://github.com/fdoganis/three_vite_xr.git

cd three_vite_xr

npm install

Run with npm run dev or use F5 in VS Code

Open http://localhost:5173 in your browser

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Tools

  • Web development

    • Web browser (Firefox, Chrome, Safari Mobile)
    • Git
    • Code Editor (VSCode)
  • Technologies

    • HTML, JS, CSS
    • WebGL, THREE.js
    • WebXR
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Install a browser (desktop)

  • Firefox installed by default
    • should be enough!
  • Chrome
    • to test compatibility and some features
    • alternative: install Chromium on Linux
      • open-source version without proprietary services
sudo apt-get install chromium-browser
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Install Git

sudo apt-get install git

git config --global user.name "myusername"
git config --global user.email myname@mymailprovider.com
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Install VSCode

sudo apt update
sudo apt install software-properties-common apt-transport-https wget

wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | sudo apt-key add -

sudo add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main"

sudo apt install code

Remove GPG warnings

sudo gpgconf --kill dirmngr
sudo chown -R $USER:$USER ~/.gnupg
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Customize VS Code

  • Avoid UI blinking by changing the settings:
set window.titleBarStyle to custom
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
  • File > Settings > Format on Save ⭐
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Local development caveats

➡️ need to run a server, like Live Server, or using Python:

$ cd /home/somedir
$ python -m SimpleHTTPServer

$ python3 -m http.server

Then open http://localhost:8000 in your browser

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Install WebXR browser (mobile)

  • Android  
    • install the latest mobile Chrome version (129+)
  • Meta Quest   🥽
    • use default Browser app
  • Apple Vision Pro   🥽
    • VR only, no AR 😢
  • iOS   📱
    • no official WebXR support 😭
    • alternatives below 👇 and here 💀
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Install iOS WebXR browser

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

"caniuse"

WebXR
Report
⭐

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Desktop WebXR Emulators

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla WebXR Emulator

  • uses WebXR Polyfill
  • fake mobile AR device
  • very convenient when you don't have an AR device or for debugging
  • hand tracking (WIP)
  • NO LONGER ACTIVE forked by Meta 👇
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Meta WebXR Emulator

source code

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR in Safari inside Apple Vision Pro Emulator

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Demo

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR Concepts

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR Basic Concepts XR + AR ⭐

  • Tracking (spaces) and geometry of the real scene:
    • detect planes and geometry (point cloud or mesh) using SLAM, or similar technologies
  • XR Frame: RGB image + camera info (pose, focal, tracking, light)
  • Hit test intersection between a virtual ray and the real scene
    • frequent constraint: RGB camera + depth estimation
  • Anchors and worldmap :
    • points of interest placed by the used
    • updated continuously as the real world gets reconstructed
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Advanced WebXR Concepts

  • Occlusion handling
    • human occlusion (ARKit)
    • real world occlusion (ARKit + LiDAR, ARCore)
  • Perception
    • of the environment (Vision, IA, LiDAR)
      • reconstruction + classification floor, wall, table
    • of the user
      • hand gestures, gaze, intentions
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Standard APIs

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Code examples : WebXR needs 3D

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR AR Module

API overview using pseudo-code

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Security constraints 🚨

  • permissions
    • camera, location, movement
  • ⚠️ https mandatory
  • requires user action to start
    • AR / VR / XR Button to switch to AR
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

AR Initialization

isSessionSupported(‘immersive-ar’);

// RequestSession on Button press
navigator.xr.requestSession

// Add listener for ARButton Press

// Request reference spaces
localReferenceSpace = await session.requestReferenceSpace(‘local');
viewerReferenceSpace = await session.requestReferenceSpace(‘viewer');

// Request hitTest

session.requestHitTestSource

// RequestAnimationFrame
// NOTE: THREE.js must use
 renderer.setAnimationLoop 
 // instead of window.requestAnimationFrame
// Or else use session.requestAnimationFrame(render)

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Draw

// On each Draw
// Callback on every draw, with an XRFrame

const render = (t, frame) => {

    const pose = frame.getViewerPose(localReferenceSpace);

    frame.getPose(localReferenceSpace, viewerReferenceSpace).transform.matrix

    const hitTestResults = frame.getHitTestResults( hitTestSource );
    const hit = hitTestResults[ 0 ];
    reticle.matrix.fromArray( hit.getPose(viewerReferenceSpace ).transform.matrix );

}
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Selection (onTouch)

Example: https://github.com/mrdoob/three.js/blob/master/examples/webxr_ar_cones.html

// Get hand, controller, or phone
controller = renderer.xr.getController( 0 ); 

// See also selectstart, selectend, squeeze etc.
controller.addEventListener( 'select', onSelect );

scene.add( controller );

// Before rendering, update the controller, and apply position to mesh (in meters)
mesh.position.set( 0, 0, - 0.3 ).applyMatrix4( controller.matrixWorld );
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Let's Code!

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

WebXR + THREE.js ⭐

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Creating your own QR code

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Build: reminders

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Replace the cone with another model

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Add XR to your THREE.js project! ⭐

Port your THREE.js project to use the real world!

  • start with THREE.js' webxr_ar_cones example above
  • replace the cone creation with your solar system
    • create the solar system only once
    • change its position if it has already been created
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Challenges 💪

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Alternative AR Libraries

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

More libraries

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

App examples

  • Many (old) examples using AR.js + THREE.js + THREEx

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

More examples

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Computer Vision

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Extras

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Courses

https://medium.com/sopra-steria-norge/get-started-with-augmented-reality-on-the-web-using-three-js-and-webxr-part-1-8b07757fc23a ⭐

https://codelabs.developers.google.com/ar-with-webxr#0

https://medium.com/arjs/webar-playground-ar-in-a-few-clicks-67a08cfb1534

https://blog.halolabs.io/building-ar-vr-with-javascript-and-html-97af4434bcf6

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Guides

https://developer.apple.com/design/human-interface-guidelines/ios/system-capabilities/augmented-reality/

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Code links : Browser-based AR and VR

http://webglworkshop.com/presentations/Workshop31-ar-vr.html#/21

https://webxr.io/webar-playground/

http://learningthreejs.com/blog/2015/07/16/hatsune-miku-dancing-in-augmented-reality/

http://studioknol.com/phase-two-building-with-virtuality/

https://github.com/rodrigocam/ar-gif
https://github.com/XingMeansOK/slamjs_samples (RGBD)

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla's (deprecated) XR Viewer (1)

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla's (deprecated) XR Viewer (2)

  • DO NOT use URLs with iframes!

For example:

https://threejs.org/examples/?q=cones#webxr_ar_cones

will NOT work (you will get a confusing "WebXR not available" message on your XR Button)

Use this URL instead:

https://threejs.org/examples/webxr_ar_cones

Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla's (deprecated) XR Viewer (3)

  • DO NOT use Dark Mode, otherwise all the colors in your 3D graphics will look inverted
    • you can force XRViewer to always use the light theme
      • check the in-app settings
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla's (deprecated) XR Viewer (4)

  • Remember to clear your cache frequently if you are developing an app and you are not seeing your code changes
    • check Data Management from the in-app settings
Fivos Doganis | Presentation licensed under CC BY-SA 4.0 | 2024

Mozilla's (deprecated) XR Viewer (5)

Settings / XRViewer / WebXR Polyfill URL : https://arenaxr.org/webxrios.js

URL copied from Anthony Rowes' "XR Browser" (maintained!) app

https://github.com/orgs/marp-team/discussions/83

https://marpit.marp.app/directives?id=tweak-theme-style

**************************

See Readme / TODO

**************************

ARKit ![height:32px](https://upload.wikimedia.org/wikipedia/commons/3/31/Apple_logo_white.svg)

WebGL stack

# Source code https://aframe.io/blog/webxr-ar-module/ https://glitch.com/edit/#!/xr-spinosaurus ``` <a-scene> <a-assets timeout="30000"> <a-asset-item id="spinosaurus" src="dino-model.glb"></a-asset-item> </a-assets> <a-camera position="0 1.2 0"></a-camera> <a-entity id="dino" position="-1 0 -3" scale="0.5 0.5 0.5"> <a-entity position="0 2.15 0" rotation="0 55 0" gltf-model="#spinosaurus" animation-mixer shadow="cast: true; receive: false"></a-entity> </a-entity> </a-scene> ``` ---

# The End!