A-FrameとAR.jsで超簡単AR（PC・スマホ・マルチマーカー対応）

# 背景と目的

2017年7月11日に [A-Frame](https://aframe.io/) のブログにて「[Creating Augmented Reality with AR.js and A-Frame](https://aframe.io/blog/arjs/)」という記事が公開されました。VR用フレームワークの [A-Frame](https://aframe.io/) と、AR用フレームワークの [AR.js](https://github.com/jeromeetienne/AR.js) の組み合わせで、超簡単なARの実装方法が紹介されています。

これまで Processing + NyARToolkit が「簡単」と感じてよく遊んできましたが、A-Frame + AR.js はもっと簡単で、PCでもスマホでも難なく動作しました。単純なコンテンツを作って遊ぶだけなら、これで十分かもしれないと感じています。

既にご存じの方も多いと思いますが、日本語情報が少なめですし、自分なりの学習結果を簡単にまとめておきます。

1. とにかく動かす
2. OBJ形式のCGモデルを表示（マルチマーカー）


＜2019/08/05 追記＞
その後、A-Frame を使った VR/AR 遊びの書籍を出しました（少し宣伝）。
『[VRアプリを作ろう: A-FrameでかんたんWebVR入門](https://www.amazon.co.jp/dp/4815012172/)』



# とにかく動かす

## 完成イメージ

マーカー上に立方体を表示させます。

[こちら](https://arjs1.bitballoon.com/)で実物を動作確認できます。
（Windows PC の Chrome と Firefox、Android スマホの Chrome で動作確認済）

![Screenshot_20170910-120013.png](https://qiita-image-store.s3.amazonaws.com/0/157570/bd7157cf-5e08-45ce-2302-f7c6d8e2bacb.png)

## コーディング

以下のようなhtmlファイルを作成します。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>A-Frame で超簡単 AR</title>
  </head>
  <body style="margin:0px; overflow:hidden;">
    <!-- A-Frame ライブラリの読み込み -->
    <script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
    <!-- AR.js ライブラリの読み込み -->
    <script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js"></script>
    
    <!-- A-Frame の VR空間に AR.js を紐づける（デバッグUIは非表示） -->
    <a-scene embedded arjs="debugUIEnabled:false;">

      <!-- マーカーを登録（プリセットされている「hiro」マーカー） -->
      <a-marker preset="hiro">
        <!-- マーカーの場所に箱を置く（見やすいようにワイヤーフレーム表示） -->
        <a-box position="0 0.5 0" wireframe="true"></a-box>
      </a-marker>

      <!-- AR用のカメラを置く -->
      <a-entity camera></a-entity>

    </a-scene>
  </body>
</html>
```

## 動作確認

### マーカーの準備

例えば[こちら](https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Hiro%20pattern.pdf)から、「hiro」マーカーをダウンロードし、PCの画面に表示させるか、プリントアウトします。

### 前提

カメラを使うため、ブラウザのセキュリティ上、**https接続が必要**です。ローカルに立てたhttpサーバでPCで試す場合、「localhost」なら大丈夫です。スマホの場合は、https対応のホスティングサービスにアップするなどします。

### PCの場合（例）
* PCでhttpサーバを動かす（例えばXAMPPのApache）
* 上のindex.htmlを公開場所に置く
* Chrome または Firefox で localhost として開く
* カメラをhiroマーカーにかざす

### スマホの場合（例）
* [BitBalloon](https://www.bitballoon.com/)にアクセス
    * アカウントを持っていればサインイン、使い捨て用途であればアカウント不要
* index.htmlが入ったフォルダごと、BitBalloonのページにドラッグ＆ドロップしてアップロード
    * アクセスURL（無作為の文字列.bitballoon.com）が表示される
* **Android** スマホの **Chrome** で、頭に **https://** を付けて上のURLを開く
    * Firefox では私の環境では動きませんでした
    * iOS11からは iPhone でも動くらしいです（私は未確認）
    * スマホは**横向き**に
* カメラをhiroマーカーにかざす

## 解説

解説不要なほど簡単ですが、流れだけ列挙します。

* script タグの srcで A-Frame と AR.js へのリンクを指定
* a-scene タグで embedded属性と arjs属性を指定
    * debugUIEnabled:false; はデバッグUIを非表示にする設定、任意です
* a-marker タグでマーカーを登録
    * 任意のマーカーも利用可能ですが、ここではプリセットの「hiro」を指定
* a-marker 要素の中に、そのマーカー検出時に表示するオブジェクトを置く
    * ここでは a-box で箱を表示
    * マーカーの中心位置が position="0 0 0"
    * マーカーの大きさが scale="1 1 1"
* 最後に a-entity にcamera属性を付けることで、AR用のカメラを置く


# OBJ形式のCGモデルを表示（マルチマーカー）

## 完成イメージ

複数のマーカーを検出させ、かつ、プリミティブだけでなく、OBJ形式のCGモデルを表示させます。おまけで、CGモデルに簡単なアニメーションも付けます。

[こちら](https://arjs2.bitballoon.com/)で実物を動作確認できます。
（Windows PC の Chrome と Firefox、Android スマホの Chrome で動作確認済）

![Screenshot_20170910-141930.png](https://qiita-image-store.s3.amazonaws.com/0/157570/1bbf6425-3b0d-26d6-93e9-2cd2e9a807be.png)


## コーディング

以下のようなhtmlファイルを作成します。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>CG モデルを登場させる</title>
  </head>
  <body style="margin:0px; overflow:hidden;">
    <!-- A-Frame ライブラリの読み込み -->
    <script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
    <!-- AR.js ライブラリの読み込み -->
    <script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js"></script>
    
    <!-- A-Frame の VR空間に AR.js を紐づける（デバッグUIを非表示） -->
    <a-scene embedded arjs="debugUIEnabled:false;">

      <!-- OBJ形式のCGモデルの読み込み -->
      <a-assets>
        <a-asset-item id="obj" src="rocket.obj"></a-asset-item>   <!-- objファイル -->
        <a-asset-item id="mtl" src="rocket.mtl"></a-asset-item>   <!-- mtlファイル -->
      </a-assets>

      <!-- マーカーを登録（プリセットされている「hiro」マーカー） -->
      <a-marker preset="hiro">
        <!-- マーカーの場所に箱を置く（見やすいようにワイヤーフレーム表示） -->
        <a-box position="0 0.5 0" wireframe="true"></a-box>
      </a-marker>

      <!-- マーカーを登録（プリセットされている「kanji」マーカー） -->
      <a-marker preset="kanji">
        <!-- マーカーの場所に OBJ 形式の 3DCG を置く -->
        <a-obj-model
          src="#obj"
          mtl="#mtl"
          scale="0.005 0.005 0.005"
          position="0 0.5 0">
          <a-animation
            attribute="rotation"
            to="0 360 0"
            dur="3000"
            easing="linear"
            repeat="indefinite">
          </a-animation>
        </a-obj-model>
      </a-marker>

      <!-- AR用のカメラを置く -->
      <a-entity camera></a-entity>
    </a-scene>
  </body>
</html>
```

## 動作確認

### CG関連ファイルの準備

ここでは、Processing の loadDisplayObj サンプルに同梱されているロケットのモデルを利用しました。
[Processing の GitHub ページ](https://github.com/processing/processing-android/tree/master/examples/Basics/Shape/LoadDisplayOBJ/data)から、以下の3個のファイルダウンロードして、index.htmlと同じフォルダ内に置きます。

* rocket.**obj** ... モデル本体
* rocket.**mtl** ... 材質ファイル
* rocket.**png** ... テクスチャ


### マーカーの準備

「hiro」マーカー（[例えばこちら](https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Hiro%20pattern.pdf)）と、「人(kanji)」マーカー（[例えばこちら](https://github.com/artoolkit/artoolkit5/blob/master/doc/patterns/Kanji%20pattern.pdf)）をダウンロードし、PCの画面に表示させるか、プリントアウトします。

### 前提（再掲）

カメラを使うため、ブラウザのセキュリティ上、**https接続が必要**です。ローカルに立てたhttpサーバでPCで試す場合、「localhost」なら大丈夫です。スマホの場合は、https対応のホスティングサービスにアップするなどします。

### PCの場合（例）
* PCでhttpサーバを動かす（例えばXAMPPのApache）
* 上のindex.htmlおよび3個のCG関連ファイルを公開場所に置く
* Chrome または Firefox で localhost として開く
* カメラをhiroマーカーと人マーカーにかざす

### スマホの場合（例）
* [BitBalloon](https://www.bitballoon.com/)にアクセス
    * アカウントを持っていればサインイン、使い捨て用途であればアカウント不要
* index.htmlおよび3個のCG関連ファイルが入ったフォルダごと、BitBalloonのページにドラッグ＆ドロップしてアップロード
    * アクセスURL（無作為の文字列.bitballoon.com）が表示される
* **Android** スマホの **Chrome** で、頭に **https://** を付けて上のURLを開く
    * Firefox では私の環境では動きませんでした
    * iOS11からは iPhone でも動くらしいです（私は未確認）
    * スマホは**横向き**に
* カメラをhiroマーカーと人マーカーにかざす


## 解説

こちらも解説不要なほど簡単ですが、最初のサンプルと違う部分だけ列挙します。

* a-assets タグ内の a-asset-item タグで、objファイルとmtlファイルを指定
    * 後でidで指定するので、必ず任意のidを付けておく
* a-marker タグでマーカーを登録
    * プリセットの「kanji」を指定
* a-marker 要素の中に、そのマーカー検出時に表示するオブジェクトを置く
    * a-obj-model でOBJ形式のCGモデルを表示
    * src属性にobjファイルのid
    * mtl属性にmtlファイルのid
    * scaleとpositionは現物合わせで適当に調整
    * おまけで a-animation でY軸まわりに回転するアニメーションを追加


# まとめと今後

A-Frame と AR.js の組み合わせで、ほんの少しのコードで AR の Webアプリを実装できました。PCでもスマホ（現状Androidのみ）でも難なく動き、マルチマーカーもOKです。

[開発者さんのポスト](https://medium.com/arjs/ar-js-supports-tango-on-a-frame-too-2c098de4df34)によると、Google Tango 対応デバイスならマーカーレストラッキングもできるようです。Apple の arkit にも対応していくそうです。

（2017/10/08 追記）iOS 11 の Safari でも動作確認しました。

今後もウォッチを続けたいと思います。