Argon.js logo

Argon.js

This site contains a collection of tutorials for web developers using argon.js to add AR content to a web application. On this page, we provide an overview of the design of argon.js, introducing the terminology and concepts used by the framework. In the tutorials, we will go through a sequence of examples that show how to leverage the various features of argon.js in a web application.

Design goals

The goal of the argon.js framework and associated Argon AR-enabled web browser (currently on iOS) is to use web technologies to create fully-registered 3D AR applications that leverage 3D graphics, geo-spatial-positioning, and computer-vision tracking (currently using Qualcomm’s Vuforia library). While all these capabilities are currently available only in the Argon browser, argon.js was designed to help developers create platform-independent AR web content that will eventually run on other platforms as the necessary features for 3D AR become available. Therefore, the central design goal of argon.js is to provide an abstraction layer between the web-app and the browser.

Abstractions

The argon.js abstractions are based around an AR Context in which AR content lives. A Context combines AR content with some representation of Reality. On a mobile phone or tablet, this Reality will usually be video-mixed AR (overlaying graphics on the video from the device's camera), but the Reality could also include geo-located panoramic images, remote video, or simple transparency on an optical see-through display, to name a few. A Reality is defined by a visual representation of the world and a Reference Frame that defines the 3D eye position of the viewer relative to the Reality's visual representation (the eye Reference Frame). Some Realities may contain more Reference Frames as well (e.g., our current Realities define an eyeOrigin reference frame that is positioned at the location of the eye, but oriented such that the z-axis points up and the y-axis points north, following geospatial conventions).

Reactive Programming

argon.js follows a reactive programming model. Programmers do not create Contexts; they either request a specific Context (e.g., one that displays a certain kind of panoramic image) or express the capabilities they need (e.g., geolocation, Vuforia vision tracking), and argon.js supplies a Context based on the capabilities of the platform. By encouraging developers to develop applications based on the capabilities they need, argon.js applications are more likely to run on new platforms as they become available.

A second reason for using a reactive programming model is to support situations where the Reality may need to change while the channel is running. The argon.js framework anticipates a future in which custom AR browsers may give users control over the way they interact with AR content, and let them (not the applications) control how they are displayed by allowing them to change their view of Reality. For example, a user might want to switch from live video to remote video to a virtual flyover of their area, while an AR application is running. Similarly, in these future browsers, users may want to run multiple AR applications simultaneously, and different application requirements may cause the browser to use different Realities for the different applications. We will be exploring these ideas with the *Argon3 browser (which already allows multiple channels to run and be visible at the same time, for example), and their needs have informed the design of argon.js.

argon.js does not prescribe or support any particular rendering or content library. Rather, it provides a uniform view of the data necessary for a real-time 3D AR application to the web developer. In our work, we have been using the three.js rendering library for 3D content and have created a utility library, argon-three.js, to simplify using Argon and Three together. This library also serves as an example of how to integrate other web content libraries with argon.js (e.g., we plan on creating a binding to the FamousEngine soon).

Frames of Reference and Local Rendering

One of Argon's main features is providing geospatial Reference Frames for all AR content and making it simple to render content relative to those Reference Frames. Programmers must therefore be aware of the relationship between the argon.js Reference Frames and the coordinate system used by a rendering library such as three.js. In Argon, all objects are represented in geospatial coordinates, using cesium.js *Entities. This allows accurate representation and manipulation of frames of reference anywhere on the Earth, and (using Cesium's INERTIAL reference frames) anywhere in celestial coordinates relative to the earth.

The geospatial coordinate system used for these reference frames is not convenient for rendering with a typical 3D graphics library: it is centered at the center of the earth, with z being the line between the north and south poles and the xy plane going through the equator. The values of objects on the surface of the earth in this frame make no intuitive sense to a developer, and the size of the numbers used in this frame can present problems to some rendering systems. Therefore, argon.js defines a localOrigin Reference Frame, which is an arbitrary location on the surface of the earth near the eye Reference Frame, oriented such that (like eyeOrigin) the z-axis is pointing up and the y-axis is pointing north. (Currently, localOrigin is initialized to the location of the device when the web application is launched, and reset when the eye is more than 5km from the localOrigin, although this implication detail may change).

In argon-three.js, the origin of the three.js scene is the localOrigin, and all objects in the three.js scene are positioned relative to it. We expect any rendering library would leverage the localOrigin similarly. By keeping the rendering camera near the origin of the world, floating point accuracy is maximized close to the user, and objects far from the origin (which may suffer floating point artifacts) are also far from the camera (minimizing the impact of those artifacts).

The implication of using an arbitrary local origin for rendering is three-fold:

  1. All content in the 3D scene (i.e., all 3D content in the world) should be a child of some Object3D in the scene that is positioned relative to some Cesium Entity (argon-three.js provides utility functions to create these relationships and maintains them automatically). argon-three.js will automatically update the position and orientation of those entities when the localOrigin changes.
  2. The absolute 3D position and orientation of content in the 3D world can change over time and has no pre-defined relationship to geospatial coordinates. To get the geospatial location of an object in the scene (e.g., of an Object3D in the three.js scene graph), the programmer must first get the geospatial coordinates of a Cesium Entity that corresponds to an Object3D that is an ancester of the object in the scene graph, and combine it with the relative position and orientation of this child object.
  3. An argon.js application should not change the position and orientation of an Object3D in the scene bound to some Cesium *Entity, as Argon will reset their position and orientation regularly.

A note about HTML5 DOM performance in 3D web applications

The performance of any web application is bound to the way an application interacts with the DOM. Any time the value of a DOM property is changed, the DOM is marked as dirty and scheduled to be repaired and refreshed. If a DOM property is read when the DOM is dirty, the entire page will be immediately repaired and reflowed before returning the value of the DOM property. In a traditional 2D web page, this guarantees that the properties are correct, and that content is updated automatically when something changes. When nothing changes, the page does not need to be refreshed.

However, in a 3D web page, such as those created with argon.js, the page is rendered continuously, at speeds of 30, 60 or more times per second. DOM repair is very expensive, and even a single extra repair will dramatically affect the performance of a 3D web app.

Therefore, we strongly advise against unnecessarily reading any DOM properties, especially after changing any properties. Similarly, property updates should also be minimized.