August 22, 2021

709 words 4 mins read

Augmenting Reality

Augmenting Reality

Projects can come from the weirdest places at times. In this case it was a friend’s random offhand comment, “it would be cool to have an AR app that would help customers visualize having our products in their homes."

There must be something like that floating around the internet, right? An opensource augmented reality (AR) project that could be modified to use different, custom, 3D models. A quick google search later, and lo and behold such projects do exist. And modifying them has proven to be surprisingly easy.

Out of the four listed projects, I decided to go with AR.js. It seemed the simplest and most straightforward tool to implement.

For this AR implementation I focused on “marker tracking”. The camera/computer scans for a specific marker; usually a barcode, QR code, or distinct logo. It then superimposes the 3D model over that marker. Using the marker’s size and position as reference for the size, orientation, and position of the 3D model.

A marker tracking AR.js service can be deployed to a browser with a few lines of HTML code. Whenever a desktop or mobile user (the “client”) wants to use the AR service, they can use their browser to access a URL of the “server”. The server then responds with an HTML file that serves as instructions for what the client machine’s browser should do to provide the AR service. All of the computation and data is processed on the client machine (your desktop or mobile phone). All the server does is provide the HTML instructions.

With all of that set up, it would look something like this:

Quick and dirty proof of concept.

Diving into the technical details of it, the HTML script (ar.html) I used for my proof of concept is:

    <script src=""></script>
    <!-- we import arjs version without NFT but with marker + location based support -->
    <script src=""></script>
    <body style="margin : 0px; overflow: hidden;">
        <a-scene embedded arjs>
            <a-asset-item id="man" src=""></a-asset-item>
        <a-marker preset="hiro">
            position="0 0 0"
            rotation="0 0 0"
            scale="1 1 1"
        <a-entity camera></a-entity>

Identifying the most important parts of this code1:

Code What it does
<script src=""></script> We import the AR.js libraries for marker tracking and location based AR to the browser.
<a-asset-item> We define what the 3D model is called (man), and where the client can find a copy of the 3D model file (src).
<a-marker> We define what marker the camera should look for to impose the 3D model. In this case we use an AR.js preset called hiro.
gltf-model For the given marker, hiro, we specify the 3D model we want to have imposed, #man, previously defined in <a-asset-item>

This HTML code then sits on a server behind a reverse proxy that serves it whenever a client device contacts it through the specified URL. In my case, I used an nginx reverse proxy to serve the HTML file. Here is a (modified) example of my nginx configuration2:

server {
listen 443 ssl;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
    root /path/to/directory;
    index ar.html;
    try_files $uri $uri/ =404;

The important fields to note in this configuration are root and index. root is the directory on the server where the HTML file that is intended to be served resides. In this example, nginx is being told that the file resides in path/to/directory And index is the actual name of the HTML file in question, in this case ar.html.

All of this then allows any user to access the AR app by going to a specified URL on their browser. Companies could then prepare QR codes on A4 sized paper and distribute them as free PDFs. Simply print the PDF, place them in the space you you would like to see the product, go to the URL, and it appears through the lens of your phone. “It would be cool to have an AR app that would help customers visualize having our products in their homes." It would be very cool indeed, and very possible.

  1. For more information on how to use AR.js please refer to their official documentation ↩︎

  2. For more information on how to use nginx please refer to their official documentation ↩︎