Giter Club home page Giter Club logo

simple-webxr-unity's Introduction

SimpleWebXR

What is SimpleWebXR ?

SimpleWebXR is a lightweight library that exposes the WebXR javascript API in your C# Unity code. Thus, after a Unity WebGL build, your app can do augmented or virtual reality in the browser.

⭐ Star if you like it !

👁️ Watch to be notified of latest updates !

Star History

Star History Chart


Compatible browsers

Works on :


Integration examples

MRTK

Mixed Reality Toolkit is a Microsoft-driven project that provides a set of components and features, used to accelerate cross-platform MR app development in Unity. It supports Hololens, Windows Mixed Reality headset, OpenVR, Ultraleap, Mobile devices and now WebXR !

The files in directory /SimpleWebXR-Demo/Assets/SimpleWebXR/Scripts/MRTK add WebXR capabilities to MRTK with the following functions: controller tracking, hand tracking, hand ray, index pointer, grip pointer and spatial pointer. Teleportation could be added.

LIVE DEMO:

Hololens 2 Oculus Quest
iOS Emulator

Fun simulation features in browser, you can simulate your Hololens, like in Unity editor :

Mouse interaction Hand simulation (MAJ/SPACE and T/Y) Scene navigation

MRTK version : 2.6.1


Simple hand tracking

SimpleWebXR supports hand tracking. This example displays a sphere on each joint of the detected hands. The radius of this sphere is given by the device. It was tested on Hololens 2 and Oculus Quest.

You need to set flags to enable hand tracking. In firefox reality, open setting panel and set dom.webxr.hands.enabled to true. In Oculus Browser, visit chrome://flags/ and enable #webxr-hands.

LIVE DEMO : ▶️ https://rufus31415.github.io/webxr/HandDetectionExample/


Spectator view

When wearing a HoloLens, we often forget that a person who does not have it on is unable to experience the wonders that we can. Spectator View allows others to see on a 2D screen what a HoloLens user sees in their world. This Microsoft project is a native spectator view app for iOS and Android. But here, the spectator view is in your browser. WebXR is optional because you can walk around the Hololens space with the keyboard and mouse.

LIVE DEMO : ▶️ https://rufus31415.github.io/sandbox/simple-webxr-spectator/

DOWNLOAD : ⏬ Hololens 2 ARM appx and dependencies

Scene for Hololens 2 (MRTK) : /Assets/SimpleWebXR/Scenes/ SpectatorViewHololens2Server.unity. To compile, this scene, do not use UWP SDK 19041, it has socket server issues.

Unity scene for Mobile (WebGL) : /Assets/SimpleWebXR/Scenes/ SpectatorViewWebXRClient.unity

Mobile Move in Hololens space with mouse/keyboard or Follow user head

Comparison with Microsoft solution :

Simple WebXR Spectator view Microsoft native spectator view
iOS YES : WebXR Viewer, Safari or Chrome (move in Hololens space with touch screen) YES (ARKit)
Android YES (Chrome) YES (ARCore)
Desktop YES, you can move in hololens space with mouse and keyboard NO
Communication Mobile/Hololens Websocket WebRTC
FPS 10 60
Calibration Touch the screen Scan a QR Code
Experimental YES NO

Paint example

This is a very basic example on how to use Simple WebXR. It uses Unity Line Renderer to draw lines in space with your hands/controllers.

LIVE DEMO : ▶️ https://rufus31415.github.io/webxr/PaintExample/

Android Hololens 2 iOS Quest Emulator

Sources are here


XR CAD file viewer

Opens 45+ 3D CAD formats in your browser (FBX, STEP, OBJ, Collada, GLTF, OnShape, ...) and now, view them in VR/AR with WebXR !

LIVE DEMO : ▶️ https://rufus31415.github.io/sandbox/3d-viewer

work in progress...


XRTK

The Mixed Reality Toolkit's primary focus is to make it extremely easy to get started creating Mixed Reality applications and to accelerate deployment to multiple platforms from the same Unity project.

LIVE DEMO : ▶️ https://rufus31415.github.io/sandbox/simple-webxr-xrtk-solvers/

iOS Emulator

work in progress...


HPTK

Hand Physics Toolkit (HPTK) is a toolkit to implement hand-driven interactions in a modular and scalable way. Platform-independent. Input-independent. Scale-independent.

I am currently studying the implementation of WebXR in this framework.

Original repo : https://github.com/jorgejgnz/HPTK-Sample

My fork and WebXR implementation : https://github.com/Rufus31415/HPTK-Sample-WebXR

LIVE DEMO : ▶️ https://rufus31415.github.io/webxr/HPTK/

(hptk)


Quick start

Import and build a sample scene

First create a new 3D project

tuto_NewProject

Download the latest release of SimpleWebXR : https://github.com/Rufus31415/Simple-WebXR-Unity/releases

Open the unitypackage file and import all resources : in tab Project, right click on Assets > Import Package > Custom Package

image

From the directory Assets/SimpleWebXR/Example/Scenes, just drag/drop a scene (for example the PaintExample) in the tab "Hierarchy" . You can play the scene, but it won't do anything (except if you are playing a MRTK sample).

Then, build the scene : File > Build Settings.... Remove all scenes from the list and click Add open scenes so that you only get the scene we are going to build.

Select the WebGL plateform and click Switch platform. Then click the Build button and create and select a Build directory next to Assets.

image

Run your build locally in your browser

Your browser should be compatible with WebXR. For a first try, you can install the emulator :

You now need a http server to serve you files. I recommend this one : https://www.npmjs.com/package/http-server

  • Just download node.js : https://nodejs.org/
  • install the server in your system with the command npm install --global http-server

You can now open a command line in your directory Build and run http-server. Open your browser to the url : http://120.0.0.1:8080 then open the inspector and you should have a tab "WebXR" from where you can select your simulated device. You can move the controllers and the headset from here.

Now click the button "Start VR" to enter in immersion. Congrats !

image

Run your build on your smartphone or headset

You can continue to host the page on your PC and serve it to other devices. The difficulty is that most browsers require a secure context for WebXR, i.e. https or localhost.

So it's a bit more complicated, but not impossible ;) ! First you need a certificate :

  • Download openssl. If you are on windows, download binaries from : http://gnuwin32.sourceforge.net/packages/openssl.htm
  • Extract and run the command : openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -config **PATH_TO_OPENSSL**\share\openssl.cnfwhere PATH_TO_OPENSSL is the absolute path to the directory you just extracted.
  • This will generate the files cert.pemand key.pem
  • Move these files in your Build directory

To serve your files, you should now run http-server -S -C cert.pem in your Build directory. You will see in the console all the URLs where the build is accessible. In your smartphone or headset, type the one with the same subnetwork than your PC. Ensure that your firewall accepts the request. On your device, the browser will say the page is not secure, but anyway, you can continue ;)

Installation

Just add these 3 files in your Unity Asset folder, then add SimpleWebXR MonoBehavior on a game object in your scene.

  • SimpleWebXR.cs: Mono Behaviour that displays the "Start AR" button and communicates with javascript. This behavior should be in your scene.
  • SimpleWebXR.jslib: Javascript plugin that is included in the application and that makes the link between the Unity engine and the WebXR session. It displays the rendering and obtains the positions and characteristics of the camera.
  • SimpleWebXR.jspre: Javascript plugin executed before the application that initializes a number of things.

Download Unity Package

Download the latest release of SimpleWebXR from : https://github.com/Rufus31415/Simple-WebXR-Unity/releases

Add from Package Manager

You can add the package com.rufus31415.simplewebxrfrom the Package Manager. Go to Window > Package Manager Click the button + > add package from git URL and enter https://github.com/Rufus31415/Simple-WebXR-Unity.git?path=/com.rufus31415.simplewebxr/, after clicking on add it can take minutes even if Unity doesn't seem busy.

image

Edit manifest.json file

For the bravest, you can edit the file Packages/manifest.json so that it contains the line :

{
  "dependencies": {
    "com.rufus31415.simplewebxr": "https://github.com/Rufus31415/Simple-WebXR-Unity.git?path=/com.rufus31415.simplewebxr/",
    ...
    ...
  }
}

Samples

You can use the examples provided in this repository as a starting point.

All sample builds can be dowloaded as a zip file from here : ⏬ https://github.com/Rufus31415/rufus31415.github.io/tree/master/webxr

Compilation

The project must be compiled in WebGL, otherwise SimpleWebXR will have no effect. You can use the "Demo" WebGL template that is provided, but you can also use the Default one. The project has been tested with Unity 2018.4 and Unity 2020.3.

Runtime

When compiled as a WebGL app, if the browser is WebXR compatible, it will display a "Start AR" or "Start VR" button on your canvas. You don't need a specific WebGL Template, so you can keep using yours.

Get started

SimpleWebXR MonoBehavior

To begin with, it is recommended to have the SimpleWebXR component active in the scene at all times. I recommend you to create a root game object "WebXR" which contains only the SimpleWebXR component.

This one will manage two things:

  • It will display the "Start AR" or "Start VR" button at the bottom of the canvas, and will start the session if the user presses it.
  • It will call to each frame the function SimpleWebXR.UpdateWebXR().

However SimpleWebXR may not be present as a component game object in the scene, but you will have to call the static function SimpleWebXR.UpdateWebXR() by yourself at each frame.

You can also add this component by code by calling the static method SimpleWebXR.EnsureInstance(). The SimpleWebXR component does not exist, it will create it on a root game object "WebXR".

Start/Stop immersive session

If the SimpleWebXR component is active in the scene, it will automatically display a button that allows the user to start an immersive WebXR session.

You can hide this button by checking the field Hide Start Button.

In addition, you can at any time in the main thread start an immersive session from your code via the static method :

SimpleWebXR.StartSession();

You can also end an immersive session by calling :

SimpleWebXR.EndSession();

In addition, the following static events are raised when an immersive session starts or stops :

⚡️ UnityEvent SimpleWebXR.SessionStart
⚡️ UnityEvent SimpleWebXR.SessionEnd

SimpleWebXR.SessionStart.AddListener(OnSessionStart); // OnSessionStart() is a method in your code called when a session starts
SimpleWebXR.SessionEnd.AddListener(OnSessionEnd); // OnSessionEnd() is a method in your code called when a session starts

Check AR/VR supported

To find out if the current browser supports WebXR, you can call these static methods from anywhere in your code:

bool isARSupported = SimpleWebXR.IsARSupported(); // 'immersive-ar' feature is supported
bool isVRSupported = SimpleWebXR.IsVRSupported(); // 'immersive-vr' feature is supported

Warning: the result of the request is asynchronous in javascript. It may be necessary to call these functions several times or to wait to get the result. For example, the SimpleWebXR component requests the capabilities at each frame in the OnGUI() function.

Check if a WebXR Session is running

The static property SimpleWebXR.InSession indicates whether a WebXR immersive session is in progress.

bool isInWebXRSession = SimpleWebXR.InSession;

Eyes

On a smartphone and tablets, only one camera is required. But on HMD (head mounted headset), a different rendering is made for each eye, so there are two active cameras.

At the start of the session, the left eye is equal to Camera.Main. If necessary a camera is created for the left eye. The characteristics of these cameras are modified at startup (clearFlags, background, clip planes, ...).

During a session, the pose and the projection matrix are updated when SimpleWebXR.UpdateWebXR() is called.

The second camera (right eye) is destroyed at the end of the immersive session.

Camera leftEye = SimpleWebXR.LeftEye; // == Camera.Main
Camera rightEye = SimpleWebXR.RightEye; // == null on smartphones and tablets

Input controllers

The SimpleWebXR.LeftInput and SimpleWebXR.RightInput fields represent left and right controllers. On smartphones either of these input sources can be used (it depends on the browser) and corresponds to the place where the user touched the screen.

WebXRInputSource leftInput = SimpleWebXR.LeftInput;
WebXRInputSource rightInput = SimpleWebXR.RightInput;

Members of class WebXRInputSource

class WebXRInputSource {

  // ⚡️ Event triggered when the browser triggers a XRSession.selectend event, which means the input source has fully completed its primary action.
  // On Oculus Quest : Back trigger button was pressed
  // On Hololens 2 : A air tap has been was performed
  // On smartphones : The screen was touched
  public readonly UnityEvent Select;

  // ⚡️ Event triggered when the browser triggers a XRSession.selectstart event, which means the input source begins its primary action.
  public readonly UnityEvent SelectStart;

  // ⚡️ Event triggered when the browser triggers a XRSession.selectend event, which means the input source ends its primary action.
  public readonly UnityEvent SelectEnd;

  // ⚡️ Event triggered when the browser triggers a XRSession.selectend event, which means the input source has fully completed its primary squeeze action.
  // On Oculus Quest : Side grip button was pressed
  public UnityEvent Squeeze;

  // ⚡️ Event triggered when the browser triggers a XRSession.selectstart event, which means the input source begins its primary squeeze action.
  public UnityEvent SqueezeStart;

  // ⚡️ Event triggered when the browser triggers a XRSession.selectend event, which means the input source ends its primary squeeze action.
  public UnityEvent SqueezeEnd;

  // Indicates if the input source exists
  public bool Available;

  // Handedness of the input source
  // WebXRHandedness.Left : left input source
  // WebXRHandedness.Right : right input source
  public WebXRHandedness Handedness;

  // Indicates that the input source is detected and its position is tarcked
  public bool IsPositionTracked;

  // Current position of the input source if the position is tracked
  public Vector3 Position;

  // Current rotation of the input source if the position is tracked
  public Quaternion Rotation;

  // Number of axes available for this input source
  public int AxesCount;

  // Current value of each axes
  public float[] Axes;

  // Number of button for this input source
  public int ButtonsCount = 0;

  // Current state of each buttons
  public readonly WebXRGamepadButton[] Buttons;

  // Describes the method used to produce the target ray, and indicates how the application should present the target ray to the user if desired.
  // WebXRTargetRayModes.None : No event has yet identified the target ray mode
  // WebXRTargetRayModes.TrackedPointer : The target ray originates from either a handheld device or other hand-tracking mechanism and represents that the user is using their hands or the held device for pointing. The orientation of the target ray relative to the tracked object MUST follow platform-specific ergonomics guidelines when available. In the absence of platform-specific guidance, the target ray SHOULD point in the same direction as the user’s index finger if it was outstretched.
  // WebXRTargetRayModes.Screen : The input source was an interaction with the canvas element associated with an inline session’s output context, such as a mouse click or touch event.
  // WebXRTargetRayModes.Gaze : The target ray will originate at the viewer and follow the direction it is facing. (This is commonly referred to as a "gaze input" device in the context of head-mounted displays.)
  public WebXRTargetRayModes TargetRayMode;

  //The input source primary action is active
  // On Oculus Quest : Back trigger button is pressed
  // On Hololens 2 : A air tap is performed
  // On smartphones : The screen is touched
  public bool Selected;

  // The input source primary squeeze action is active
  // On Oculus Quest : Side grip button is pressed
  public bool Squeezed;

  // Constains hand joints poses, if hand tracking is enabled
  public WebXRHand Hand; 

  // Applies haptic pulse feedback to a controller 
  // intensity : Feedback strength between 0 and 1
  // duration : Feedback duration in milliseconds
  public void HapticPulse(float intensity, float duration)
}

Also, the events select, squeeze, ... can be handled at the SimpleWebXR class level via the following WebXRInputEvent static events where the first argument is the input source that raised it.

⚡️ WebXRInputEvent SimpleWebXR.InputSourceSelect
⚡️ WebXRInputEvent SimpleWebXR.InputSourceSelectStart
⚡️ WebXRInputEvent SimpleWebXR.InputSourceSelectEnd
⚡️ WebXRInputEvent SimpleWebXR.InputSourceSqueeze
⚡️ WebXRInputEvent SimpleWebXR.InputSourceSqueezeStart
⚡️ WebXRInputEvent SimpleWebXR.InputSourceSqueezeEnd

// Event triggered when a input sources has been added or removed.
⚡️ UnityEvent SimpleWebXR.InputSourcesChange

Similarly, haptic feedback on controllers can also be called at the static SimpleWebXR class level.

  // Applies haptic pulse feedback to a controller 
  // hand : Left or Right
  // intensity : Feedback strength between 0 and 1
  // duration : Feedback duration in milliseconds
  public static void HapticPulse(WebXRHandedness hand, float intensity, float duration)

Members of class WebXRGamepadButton

WebXRGamepadButton Describes a button, trigger, thumbstick, or touchpad data.

This class maps the information retrieved in javascript via the WebXR Gamepads Module API : https://www.w3.org/TR/webxr-gamepads-module-1

class WebXRGamepadButton {

  // The amount which the button has been pressed, between 0.0 and 1.0, for buttons that have an analog sensor
  public float Value;

  // The touched state of the button
  public bool Touched;
  
  // The pressed state of the button
  public bool Pressed;   
}

Members of class WebXRHand

WebXRHand describes the poses of hand skeleton joints

This class maps the information retrieved in javascript via the WebXR Hand Input Module API : https://www.w3.org/TR/webxr-hand-input-1

class WebXRHand {

  // Indicates if hand tracking is available
  public bool Available;

  // Poses of hand skeleton joints
  public WebXRJoint[] Joints;
  
  // 25 joints are tracked
  public const int JOINT_COUNT = 25;
  
  // Index of each joint in Joints array :  
  public const int WRIST = 0;

  public const int THUMB_METACARPAL = 1;
  public const int THUMB_PHALANX_PROXIMAL = 2;
  public const int THUMB_PHALANX_DISTAL = 3;
  public const int THUMB_PHALANX_TIP = 4;

  public const int INDEX_METACARPAL = 5;
  public const int INDEX_PHALANX_PROXIMAL = 6;
  public const int INDEX_PHALANX_INTERMEDIATE = 7;
  public const int INDEX_PHALANX_DISTAL = 8;
  public const int INDEX_PHALANX_TIP = 9;

  public const int MIDDLE_METACARPAL = 10;
  public const int MIDDLE_PHALANX_PROXIMAL = 11;
  public const int MIDDLE_PHALANX_INTERMEDIATE = 12;
  public const int MIDDLE_PHALANX_DISTAL = 13;
  public const int MIDDLE_PHALANX_TIP = 14;

  public const int RING_METACARPAL = 15;
  public const int RING_PHALANX_PROXIMAL = 16;
  public const int RING_PHALANX_INTERMEDIATE = 17;
  public const int RING_PHALANX_DISTAL = 18;
  public const int RING_PHALANX_TIP = 19;

  public const int LITTLE_METACARPAL = 20;
  public const int LITTLE_PHALANX_PROXIMAL = 21;
  public const int LITTLE_PHALANX_INTERMEDIATE = 22;
  public const int LITTLE_PHALANX_DISTAL = 23;
  public const int LITTLE_PHALANX_TIP = 24;
}

Members of class WebXRJoint

WebXRJoint describes a joint of a hand. Each hand is made up many bones, connected by joints.

class WebXRJoint {

  // Position of the joint
  public Vector3 Position;
  
  // Rotatiuon of the joint
  public Quaternion Rotation;

  // Optional joint radius that can be used to represent the joint has a sphere.
  // float.NaN if not supported
  public float Radius;
}

Useful WebXR content

License: MIT 😘

©Rufus31415

See the license file for details.

Sponsor 💛

You are more than welcome to sponsor me !

❤️ Sponsor

In order to maintain SimpleWebXR and ensure its proper functioning on all platforms, I have to acquire a lot of expensive equipment.

I currently have: Microsoft Hololens 2, Oculus Quest 1 & 2, Acer WMR Headset, iPad and iPhone.

What I would like to buy soon : Magic Leap, Android tablet and smartphone


                                                          
Sponsors
                                                          

                                                          
Stephen Hodgson
Maurice Frank

Any questions ?

Feel free to contact me :

simple-webxr-unity's People

Contributors

dawaralvi avatar keveleigh avatar rufus31415 avatar stephenhodgson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-webxr-unity's Issues

Fails to compile in Unity 2021.3.3

Really cryptic error from unity.

Building Library\Bee\artifacts\WebGL\build\debug_WebGL_wasm\build.js failed with output:
C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\tools\acorn-optimizer.js:1845
  throw err;
  ^

SyntaxError: Unexpected token (4460:62)
  var textEncoder={encoding:"utf-8",encode:encode(input = '') {
                                                              ^

    at Parser.pp$4.raise (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2927:15)
    at Parser.pp.unexpected (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:698:10)
    at Parser.pp.expect (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:692:28)
    at Parser.pp$3.parseObj (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2563:14)
    at Parser.pp$3.parseExprAtom (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2302:19)
    at Parser.pp$3.parseExprSubscripts (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2129:21)
    at Parser.pp$3.parseMaybeUnary (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2106:19)
    at Parser.pp$3.parseExprOps (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2041:21)
    at Parser.pp$3.parseMaybeConditional (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:2024:21)
    at Parser.pp$3.parseMaybeAssign (C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\node_modules\acorn\dist\acorn.js:1997:21) {
  pos: 166718,
  loc: Position { line: 4460, column: 62 },
  raisedAt: 166719
}
emcc2: error: '"C:/Program Files/Unity/Hub/Editor/2021.3.3f1/Editor/Data/PlaybackEngines/WebGLSupport/BuildTools/Emscripten/node/node.exe" "C:\Program Files\Unity\Hub\Editor\2021.3.3f1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\Emscripten\emscripten\tools\acorn-optimizer.js" C:\Users\KEVINA~1\AppData\Local\Temp\emscripten_temp_gz1uwi0k\build.js.pp.js AJSDCE minifyWhitespace' failed (1)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

I found a related thread, where the issue was happening in another javascript plugin, but the solution seems unrelated.
endel/NativeWebSocket#53

How to enable teleportation?

Hello,
Thank you for this very useful package.
I am new to WebGL, but I have some experience with MRTK.
I am trying to use teleportation in the Oculus browser. But I can't get it to work.
In MixedRealityToolkit it is active.

image

Do I have to do something else to activate it?
Merci!

High DPI rendering issue with Unity 2020

With Unity 2020, by default, the rendering of the 2 eyes is not correct:

  • A part of the right eye is rendered on the left eye
  • The right eye is not fully rendered and there is a black border on the left side

The problem does not occur on other browsers

On the Quest 1 : window.devicePixelRatio = 0.800000011920929

Minimal.Framework.js :

  function _JS_SystemInfo_GetPreferredDevicePixelRatio() {
    return Module.devicePixelRatio || window.devicePixelRatio || 1
  }

Either add the property devicePixelRatio: 1 in the config object of index.html or force Module.devicePixelRatio in SimpleWebXR.jspre

com oculus browser-20210601-231905

Refactor project

Refactor project :

  • Use only one Unity project
  • Use MRTK as Unity package
  • Move Unity project to root
  • Create a show case carousel

Left and Right camera settings

In some cases, it is desirable to have camera settings like layers, tags and so on exposed for customisation, to enable stereoscopic effects or hiding layers.

Having the camera rig generated at run time is a barrier to this kind of customisation.

Tested on Oculus Quest Browser

This is forcing resolution really low for some reason

Without this package, my build loads webgl in mobile and desktop browser at the same resolution as the assets are set to in unity. For example, a picture at 1080p is 1080p on mobile and desktop. Once this package is attached to my project, the same build with no additional changes will visually look like maybe 720p on desktop and like 140p on mobile browser. Is this forced somewhere in a script? I know it is not my webgl template because I use the same one, the only difference is adding this package? Can I remove this forced reduction manually without breaking anything? Thanks.

URP Support (Android)

Hi,

Thanks for putting the tool together.

I'm wondering if it supports URP?.

I managed to succesfully run it using surface shader (3D project) but for URP I'm getting errors.

Tried 2 times once with clean URP project and second with upgrade of existing working surface-shader project to URP - same errors.

Thanks,
Chris

PS: error if that helps at all

exception thrown: RangeError: Maximum call stack size exceeded,RangeError: Maximum call stack size exceeded
    at stackSave (https://192.168.1.114/Build/0.1.wasm:wasm-function[798]:0x6d82e)
    at https://192.168.1.114/Build/0.1.framework.js:27278:36
    at invoke_ii (https://192.168.1.114/Build/0.1.framework.js:17358:11)
    at __ZL34GetTypeInfoFromTypeDefinitionIndexi (https://192.168.1.114/Build/0.1.wasm:wasm-function[37763]:0xdcfdf6)
    at __ZN6il2cpp2vm14GlobalMetadata21GetTypeInfoFromHandleEPK27___Il2CppMetadataTypeHandle (https://192.168.1.114/Build/0.1.wasm:wasm-function[37824]:0xdd184b)
    at __ZN6il2cpp2vm14GlobalMetadata19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37823]:0xdd183e)
    at __ZN6il2cpp2vm13MetadataCache19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37820]:0xdd17fc)
    at __ZN6il2cpp2vm4Type8GetClassEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37724]:0xdcebaf)
    at __ZN6il2cpp2vm5Class14FromIl2CppTypeEPK10Il2CppTypeb (https://192.168.1.114/Build/0.1.wasm:wasm-function[37706]:0xdce56f)
    at __ZL18FromTypeDefinitioni (https://192.168.1.114/Build/0.1.wasm:wasm-function[37764]:0xdd0126)
    at _GC_call_with_alloc_lock (https://192.168.1.114/Build/0.1.wasm:wasm-function[39292]:0xe0133e)
    at Object.dynCall_ii (https://192.168.1.114/Build/0.1.framework.js:27543:37)
    at invoke_ii (https://192.168.1.114/Build/0.1.framework.js:17360:30)
    at __ZL34GetTypeInfoFromTypeDefinitionIndexi (https://192.168.1.114/Build/0.1.wasm:wasm-function[37763]:0xdcfdf6)
    at __ZN6il2cpp2vm14GlobalMetadata21GetTypeInfoFromHandleEPK27___Il2CppMetadataTypeHandle (https://192.168.1.114/Build/0.1.wasm:wasm-function[37824]:0xdd184b)
    at __ZN6il2cpp2vm14GlobalMetadata19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37823]:0xdd183e)
    at __ZN6il2cpp2vm13MetadataCache19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37820]:0xdd17fc)
    at __ZN6il2cpp2vm4Type8GetClassEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37724]:0xdcebaf)
    at __ZN6il2cpp2vm5Class14FromIl2CppTypeEPK10Il2CppTypeb (https://192.168.1.114/Build/0.1.wasm:wasm-function[37706]:0xdce56f)
    at __ZL18FromTypeDefinitioni (https://192.168.1.114/Build/0.1.wasm:wasm-function[37764]:0xdd0126)
    at _GC_call_with_alloc_lock (https://192.168.1.114/Build/0.1.wasm:wasm-function[39292]:0xe0133e)
    at Object.dynCall_ii (https://192.168.1.114/Build/0.1.framework.js:27543:37)
    at invoke_ii (https://192.168.1.114/Build/0.1.framework.js:17360:30)
    at __ZL34GetTypeInfoFromTypeDefinitionIndexi (https://192.168.1.114/Build/0.1.wasm:wasm-function[37763]:0xdcfdf6)
    at __ZN6il2cpp2vm14GlobalMetadata21GetTypeInfoFromHandleEPK27___Il2CppMetadataTypeHandle (https://192.168.1.114/Build/0.1.wasm:wasm-function[37824]:0xdd184b)
    at __ZN6il2cpp2vm14GlobalMetadata19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37823]:0xdd183e)
    at __ZN6il2cpp2vm13MetadataCache19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37820]:0xdd17fc)
    at __ZN6il2cpp2vm4Type8GetClassEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37724]:0xdcebaf)
    at __ZN6il2cpp2vm5Class14FromIl2CppTypeEPK10Il2CppTypeb (https://192.168.1.114/Build/0.1.wasm:wasm-function[37706]:0xdce56f)
    at __ZL18FromTypeDefinitioni (https://192.168.1.114/Build/0.1.wasm:wasm-function[37764]:0xdd0126)
    at _GC_call_with_alloc_lock (https://192.168.1.114/Build/0.1.wasm:wasm-function[39292]:0xe0133e)
    at Object.dynCall_ii (https://192.168.1.114/Build/0.1.framework.js:27543:37)
    at invoke_ii (https://192.168.1.114/Build/0.1.framework.js:17360:30)
    at __ZL34GetTypeInfoFromTypeDefinitionIndexi (https://192.168.1.114/Build/0.1.wasm:wasm-function[37763]:0xdcfdf6)
    at __ZN6il2cpp2vm14GlobalMetadata21GetTypeInfoFromHandleEPK27___Il2CppMetadataTypeHandle (https://192.168.1.114/Build/0.1.wasm:wasm-function[37824]:0xdd184b)
    at __ZN6il2cpp2vm14GlobalMetadata19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37823]:0xdd183e)
    at __ZN6il2cpp2vm13MetadataCache19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37820]:0xdd17fc)
    at __ZN6il2cpp2vm4Type8GetClassEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37724]:0xdcebaf)
    at __ZN6il2cpp2vm5Class14FromIl2CppTypeEPK10Il2CppTypeb (https://192.168.1.114/Build/0.1.wasm:wasm-function[37706]:0xdce56f)
    at __ZL18FromTypeDefinitioni (https://192.168.1.114/Build/0.1.wasm:wasm-function[37764]:0xdd0126)
    at _GC_call_with_alloc_lock (https://192.168.1.114/Build/0.1.wasm:wasm-function[39292]:0xe0133e)
    at Object.dynCall_ii (https://192.168.1.114/Build/0.1.framework.js:27543:37)
    at invoke_ii (https://192.168.1.114/Build/0.1.framework.js:17360:30)
    at __ZL34GetTypeInfoFromTypeDefinitionIndexi (https://192.168.1.114/Build/0.1.wasm:wasm-function[37763]:0xdcfdf6)
    at __ZN6il2cpp2vm14GlobalMetadata21GetTypeInfoFromHandleEPK27___Il2CppMetadataTypeHandle (https://192.168.1.114/Build/0.1.wasm:wasm-function[37824]:0xdd184b)
    at __ZN6il2cpp2vm14GlobalMetadata19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37823]:0xdd183e)
    at __ZN6il2cpp2vm13MetadataCache19GetTypeInfoFromTypeEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37820]:0xdd17fc)
    at __ZN6il2cpp2vm4Type8GetClassEPK10Il2CppType (https://192.168.1.114/Build/0.1.wasm:wasm-function[37724]:0xdcebaf)
    at __ZN6il2cpp2vm5Class14FromIl2CppTypeEPK10Il2CppTypeb (https://192.168.1.114/Build/0.1.wasm:wasm-function[37706]:0xdce56f)
    at __ZL18FromTypeDefinitioni (https://192.168.1.114/Build/0.1.wasm:wasm-function[37764]:0xdd0126)
printErr @ 0.1.loader.js:69
callMain @ 0.1.framework.js:29112
doRun @ 0.1.framework.js:29135
run @ 0.1.framework.js:29147
runCaller @ 0.1.framework.js:29083
removeRunDependency @ 0.1.framework.js:1163
(anonymous) @ 0.1.loader.js:697
Promise.then (async)
(anonymous) @ 0.1.loader.js:680
callRuntimeCallbacks @ 0.1.framework.js:1000
preRun @ 0.1.framework.js:1029
run @ 0.1.framework.js:29125
runCaller @ 0.1.framework.js:29083
removeRunDependency @ 0.1.framework.js:1163
receiveInstance @ 0.1.framework.js:1261
receiveInstantiatedSource @ 0.1.framework.js:1276
Promise.then (async)
doNativeWasm @ 0.1.framework.js:1289
(anonymous) @ 0.1.framework.js:1359
unityFramework @ 0.1.framework.js:21076
(anonymous) @ 0.1.loader.js:674
Promise.then (async)
loadBuild @ 0.1.loader.js:673
(anonymous) @ 0.1.loader.js:717
createUnityInstance @ 0.1.loader.js:702
script.onload @ (index):93
load (async)
(anonymous) @ (index):92

spectator example: an insecure websocket connection may not be initiated from a page loaded over https

I have problems to make the spectator example work.

Desktop:
After entering ip address of hololens the browser shows a message "an insecure websocket connection may not be initiated from a page loaded over https".
In Chrome this can be bypassed by site settings > Insecure content > Allow.
After this bypass the example works

Ipad:
Nothing happens after entering the ip address. I suspect the socket connection is also blocked but without message.

Android:
Somehow I can only load the app in Firefox, but not in Chrome because of memory limitations.
Firefox also fails with the message "SecurityError: The operation is insecure". I didn't find a way to bypass this on Firefox.

Is it possible to switch to secure websocket in the spectator example?

MSAA support

would be nice to get anti-aliasing working without the framerate hit. For example 4x MSAA

Tested on Oculus Quest Browser

iOS Support for Safari

Hello,

since we have experimental features for WebXR and Safari since iOS 16, I think we should start looking into it. In general, this needs to be enabled first in the Settings for Safari (Advanced > Experimental Features > check all the WebXR thingies).

However, we weren't able to run our application, which works in "WebXR Viewer".

Any ideas, what is missing? I can't debug it right now, since I don't have a Mac at hand but I'll try later.

Stuck on loading

Hello, I add the SimpleWebXR.unitypackage, and build Paint scene. But I stuck on loading.
image

Regression. VR scale no longer matches Unity editor scale on Oculus Quest

I recently tried the latest version of your plugin, and found that the scale of the scene is now based on the height of the headset at player start. The camera in my editor scene is at a seated height. If I start the build when I am standing, scene scale is huge and I feel like a hobbit. If I start the scene when crouched, scene scale is tiny and I feel like a giant. It is very important to my use (showing clients models of real world exhibit spaces) to have the scale in VR match the scale in Unity. A previous version of your plug-in that I have used (dated Dec 3) did not have this issue.

Visualize controller 3D model and animate it

AR Foundation Image Tracking Demo

Hello there,

i forked Unity-Technologies/arfoundation-demos and setup the project in Unity 2019.4.13f1 as described here by adding the 3 mentioned files the Unity Asset folder and attachting SimpleWebXR MonoBehavior on a game object called WebAR to my scene (commit).

I fired up a simple HTTP Server python -m SimpleHTTPServer 8080 and a tunnel via ngrok http --host-header=rewrite 8080 to access index.html from my actual smartphone (Apple iOS) via a public URL.

The websites loads extremly slow (2-3 Minutes) with a 100Mbit internet connection. After loading finished, there is no camera image (just a black screen) with a Text saying "Wait for tracking to begin."

The Webserver also returns a 404:

GET /sharedassets0.resource              404 File not found

The file sharedassets0.resource is not part of the bundle (not sure if this is important).

Screenshot 2020-10-28 at 11 11 33

Here are my WebGL Player Settings (maybe i forgot a important checkmark somewhere?)

Screenshot 2020-10-28 at 11 21 02

Screenshot 2020-10-28 at 11 21 07

Sidenote: The arfoundation-demos are working as expected when i export the iOS and Android Player and run it on my test devices.

Use several shared arrays between jslib and Unity

There are now 2 shared arrays (float and byte).
To limit the number of index computations and bugs, it would be interesting to have the following shared arrays:
Byte arrays :

  • left controller info
  • right controller info
  • left view info
  • right view info
  • global info

Float arrays :

  • left controller poses
  • right controller poses
  • left view poses / matrix
  • right view poses / matrix

black flickering on mesh

UpdateCamera(WebXRViewEyes eye) is causing black flickering

When I disable that function, no flickering

MRTK 2.7.3 Support

Do you know of any blockers for supporting 2.7.3? I can take a stab at it, but would love some guidance if it's already been attempted. Thanks!

Painter not working on Smartphone (Android)

Hey there,

I was looking for an webxr exporter for my projects (mainly AR on phones) and on testing the examples I saw that the painter is not working on my device (Samsung S8) in any of the browsers. Camera has passthrough but there is not paint working.

How to enable Spatial Awareness on Android?

Hi, I am trying to replicate your show case WebXR on Android with MRTK.

I want to enable Spatial Awareness like this.
move

But, I am not able to do it.
I enabled it in MTRK ToolKit. But it doesn't work,
image

What should I do to activate it?
My current set up:
Unity 2019.4.23
MRTK 2.7
Android 8

Thank you for your help

Unable to do hand tracking MRTK on browser

I tried your project Simple-WebXR-Unity Hand Detection Example and MRTK Hand Interaction. But both of them just can't do hand tracking on my browser. The MRTK Hand Interaction only can interact with the 3d object using controller. I use Magic Leap Helio browser. Do you know why i can't do the hand tracking ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.