おもちゃラボ

Unityで遊びを作ってます

Unityで始めるARKit入門 画像トラッキング編

今回はARKit1.5から使えるようになったARマーカーについて紹介します。この機能を使うとVuforiaやARToolKitのように、自分の使いたいマーカー画像の上にARでモデルを表示することができます

f:id:nn_hokuson:20181010193524j:plain:w600

Unityを使ってARKitを学ぶためのまとめ記事はこちらです。
ARKitの各種機能の紹介と、ARKitを使ったもぐらたたきの作り方を紹介しています。
こちらも参考にしてみて下さい。
nn-hokuson.hatenablog.com
 

ARKitと画像トラッキング

ARマーカーを使ってARを表示する仕組みは、前回までの平面を認識する仕組みとは大きく異なります。

平面認識が空間中の特徴点から平面を算出していました。それに対して、VuforiaなどのARマーカーを使ったARでは映像中のマーカーの歪み方から、カメラの位置を計算してARを表示します。

nn-hokuson.hatenablog.com

ARKit1.5までは「動かない画像」しかマーカーにすることができませんでした。しかし、ARKit2.0ではARImageTrackingConfigurationというコンフィギュレーションが導入され、マーカーを動かしてもその上にARモデルを表示し続ける(画像トラッキング)ことができるようになりました。

ただ、残念なことに2018年10月現在、UnityからARKit Pluginを通してARImageTrackingConfigurationを使用することができません。ここでは従来の手法を使ってARを表示する方法を紹介します。

booth.pm

UnityとARKitで画像トラッキングする流れ

ARKit Pluginで画像トラッキングをするには次の手順が必要になります。

  1. 画像マーカー(ARReferenceImage)を登録する
  2. 画像セット(ARReferenceImageSet)に追加する
  3. 画像セットを登録する
  4. 画像と表示するモデルを関連づける

f:id:nn_hokuson:20181010191839j:plain:w500

UnityのARKit Pluginでは画像マーカーをARReferenceImageとして扱います。使用したい画像をARReferenceImageとして用意し、それをARReferenceImageSetに登録します。作成したセットはCamera Managerに登録します。最後にGenerateImageAnchorスクリプトを使って画像マーカーとモデルを関連づけます。

プロジェクトの作成

今回も前回と同様ARKit Pluginを使用します。まだダウンロードしていない人は下記のURLからダウンロードしてください。

https://bitbucket.org/Unity-Technologies/unity-arkit-plugin/get/arkit2.0_beta.zip

また、セットアップ手順などはこちらで説明しています。

nn-hokuson.hatenablog.com

UnityARKitPlugin/Examples/ARKit1.5/UnityARImageAnchorのプロジェクトを開いてください。

f:id:nn_hokuson:20181010184745j:plain

このプロジェクトにはUnityのロゴが書かれた2つのARマーカーが登録されています。ここでは、これらに加えて次のマーカ(姫路城!)を使用します。

f:id:nn_hokuson:20181010192854j:plain:w256

画像マーカー(ARReferenceImage)を登録する

上記の画像をReferenceImagesフォルダに追加しましょう(別のフォルダでも問題ありません)追加できたらプロジェクトウインドウで右クリックして、「Create」→「UnityARKitPlugin」→「ARReferenceImage」 を選択して(ファイル名はTestReferenceImageにしました)ください。

f:id:nn_hokuson:20181010184821p:plain:w100

続いて今作成したTestReferenceImageにマーカーの情報を登録します。インスペクタから次のように登録してください。Image Textureには先ほど登録した画像をドラッグ&ドロップします。Physical SizeはARマーカーの大きさ(単位はm)です。Physical Sizeが0のままだとXcodeのビルド時にエラーが出ます。
 

項目名 設定値
Image Name Test
Image Texture ARマーカー画像
Physical Size 0.05

f:id:nn_hokuson:20181010184844p:plain:w300

画像セット(ARReferenceImageSet)に追加する

作成したARReferenceImageを画像セットに登録します。新規で画像セットを作っても良いのですが、もうすでに用意されているものがあるので、ここではそれを利用しましょう。

プロジェクトウィンドウでARImageSet_UnityLogoを選択して、インスペクタのReference ImagesのSizeを3に設定してください。そしてElement3に先程のTestReferenceImageをドラッグ&ドロップします。

f:id:nn_hokuson:20181010185649p:plain:w300

このImageSetに登録した画像がARマーカーとして検出される対象になります。

画像セットを登録する

次に上のステップで作成したARReferenceImageSetをシステムに登録します。といってもこちらもすでに登録済みですので、内容だけ確認しておきましょう。

ヒエラルキーウインドウでARCameraManagerを選択します。インスペクタのUnityARCameraManagerのImage Trackingの項目を見てください。Detection Imagesに先程の画像セットが登録されています。

今回は合計で3枚のARマーカーを用意したので、Maximum Number of Trcked Imagesの値は「3」に変更しておきましょう。

f:id:nn_hokuson:20181010185035p:plain:w300

画像と表示するモデルを関連づける

最後に登録したARマーカーを映したときに、マーカー上に表示する3Dモデルを決めます。今回も表示するモデルには次のアセットを使用させてもらいました。

ヒエラルキーウインドウで「Create」→「Create Empty」で空のゲームオブジェクトを作ります。次に作成したオブジェクトを選択した状態で「Add Component」→「Generate Image Anchor」スクリプトをアタッチします。

f:id:nn_hokuson:20181010185152j:plain

スクリプトのReferenceImageに「TestReferenceImage」、Prefab To GenerateにリンゴのPrefabをそれぞれドラッグ&ドロップしてください。

f:id:nn_hokuson:20181010185239p:plain:w350

ターゲットの画像マーカーが見つかった場合は、Generate Image Anchorの中のAddImageAnchorが呼び出されます。また、画像マーカーの位置が更新された場合にはUpdateImageAnchorが呼び出されます。

RemoveImageAnchorもありますが、これは画像マーカーが画面外に出たときに呼び出されるわけではありません。明示的に次のスクリプトでAnchorを破棄したときにのみ呼び出されます。

UnityARSessionNativeInterface.GetARSessionNativeInterface().RemoveUserAnchor( arImageAnchor.identifire );

画像トラッキングの確認

これでUnityとARKitを使って画像トラッキングを行う準備は完了です。実際にビルドして正しく動くか確認してみてください。

ビルドする際にはBuild SettingsのScenes In Buildの項目に、UnityARImageAnchorのシーンをドラッグ&ドロップで追加するのを忘れないようにしましょう。

f:id:nn_hokuson:20181010185934p:plain:w450

正しく設定できていれば、ARマーカーを映すとARでリンゴの3Dモデルが表示されます。UnityかXcodeの設定で、ビルドのターゲットはiOS12にしておかないとエラーが出る可能性があります。

f:id:nn_hokuson:20181010194001g:plain:w500

Swiftで学ぶARKit

ここまでUnityとARKit Pluginを使って画像トラッキングをする方法を紹介してきました。Unityを使うと3Dモデルの準備やアニメーションが簡単な一方で、現在のところARImageTrackingConfigurationが使えないため、効率的な画像トラッキングができません。

したがって、今のところ画像トラッキングに関しては、Swiftから直接ARKitを使ったほうが速度もロバスト性も高いものを作ることができます。

SwiftでARKitを試したい場合は、ぜひ拙書の「ARKit超入門」を見ていただければと思います。もちろんARKitを使って画像トラッキングをする方法も紹介しています!

booth.pm

「SwiftでつくるARKit超入門」を発売しました

今話題のARKitを使ってみたいけど、何から始めたら良いのかわからない・・・。そんな人のためにARKitの入門書を書きました!本書ではSwiftとXcodeを使ってプログラムを作っていきます。「ARKit超入門」はBOOTHで販売中です!

booth.pm

「ARKit超入門」では、swiftとARKitを使って次のような16個のサンプルを作成していきます。この中のいくつかのアプリについては、もう少し詳しく紹介していきますね。

f:id:nn_hokuson:20181008001126j:plain:w350

ARKit超入門の特徴

この本ではXcodeとSwiftを使ってARKitのサンプルを作っていきます。

UnityからでもARKit用のPluginを使えば勉強はできます。ただ、ビルドに時間がかかったり、APIが異なっていたりと、ARKitの勉強という意味では効率的ではありません。

そこで、XcodeとSwiftを使ってネイティブ環境で開発することで短いサイクルで15個のアプリを開発できるように工夫しています。それぞれの章で作るアプリはARKitの機能が分かりやすいように簡単なものになっています。
f:id:nn_hokuson:20190607213337j:plain:w320f:id:nn_hokuson:20190607213343j:plain:w320
また、ARKitで使用する3Dモデルの表示にはSceneKitというAppleが開発したフレームワークを使用しています。初めての方でも簡単に理解できるように、必要な考え方はTIPSや表なども使って詳しく説明しています。
f:id:nn_hokuson:20190607213740j:plain:w320f:id:nn_hokuson:20190607213747j:plain:w320

ARKit2.0にも対応

ARKit超入門では2018年にリリースされたばかりのARKit2.0にも対応しています。ARKit2.0では、次のような機能が追加されました。

  • 環境マッピング
  • ARの永続化
  • 複数人でのAR空間の共有
  • 画像トラッキング

ARKit入門ではこれらの4つの機能についても詳しく説明しています。もちろんこれらの機能を使ったサンプルアプリケーションもついています!
f:id:nn_hokuson:20190607214611j:plain:w320f:id:nn_hokuson:20190607214619j:plain:w320
また、ARの永続化や複数人でのAR空間の共有など、少し理解しにくい部分については、イラストなどを使ってわかりやすく解説しているので、安心して読み進めていただけます。
f:id:nn_hokuson:20190607214337j:plain:w320f:id:nn_hokuson:20190607214343j:plain:w320

作れるアプリケーションと目次

「ARKit超入門」の目次は次のようになります。最後の2章では少し実践的な「距離測定アプリ」と「メジャーアプリ」を作成します。これらの章については、XcodeやInterface Builderの使い方も含めてしっかり説明しています!

目次は次のようになります。

1章 ARKitとは
2章 サンプルを動かしてみる
3章 ARKitで特徴点を検出
4章 ARKitで平面の上に球を置く
5章ARKitで平面を表示する
6章 壁を検出する
7章 タップした平面に3Dモデルを置く
8章 オリジナルの3Dモデルを置く
9章 光源を推定する
10章 環境マッピング
11章 画像マーカーを使ってARを表示
12章 面の形状に沿った平面の検出
13章 ARKitと物理挙動の連携
14章 AR空間の永続化
15章 複数人でARを共有する
16章 距離測定アプリを作る
17章 メジャーアプリを作る

本書はPDFのダウンロード版のみの販売です。全128ページで販売価格は2000円になります。ダウンロードは次のBOOTHのサイトからお願いします!

2019年秋に予定されているARKit3への対応も順次行う予定です。一度ご購入いただくと、PDFのアップデートは無料でダウンロードできます。安心してお買い求めください。

booth.pm

Unityで始めるARKit超入門 平面をシェーダで描画する

UnityのARKitについてくる平面検出マーカーって、見やすいですけどイケてないですよね。そこで、Unityのシェーダを使って、ARKitの平面検出マーカーを少しだけかっこよくする方法を紹介します。今回は上のようなドットで書かれた平面マーカーを作ってみましょう。

f:id:nn_hokuson:20181001192028j:plain

平面描画用の水玉シェーダを作成する

 上のようなドット柄の平面検出マーカーを作るだけなら、ドット模様(水玉模様)のテクスチャを用意して貼り付ければ良い気もしますね。ただ、平面が大きくなるとテクスチャも引き伸ばされるため、あまりきれいな表示になりません。

f:id:nn_hokuson:20181001185311p:plain:w300

シェーダを使って描画することで、平面の大きさによらず一定の間隔でドットを打てるのでシェーダを使った方法をオススメします。

 

水玉シェーダを作成する

まずはシーンビューで右クリックして「Create」→「Shader」→「Standard Surface Shader」を選択してシェーダファイルを作成します。ファイル名はARPlaneShaderにしておきます。

次のプログラムを入力してください。

Shader "Custom/ARPlaneShader"
{
  properties
  {
    _Ratio("Ratio", float) = 1
  }
  SubShader {
    Blend SrcAlpha OneMinusSrcAlpha
    Pass {
      Tags { "Queue"="Transparent" "RenderType" = "Transparent" }

      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
       #include "UnityCG.cginc"

      struct appdata
      {
        float4 vertex : POSITION;
        float2 uv   : TEXCOORD0;
      };

      struct v2f
      {
        float4 position : SV_POSITION;
        float2 uv     : TEXCOORD0;
      };

      v2f vert (appdata input)
      {
        v2f output;
        output.position = UnityObjectToClipPos(input.vertex);
        output.uv = input.uv;
        return output;
      }

     float _Ratio;
      fixed4 frag (v2f input) : SV_Target
      {
        float2 v = float2(input.uv.x * 200 * _Ratio, input.uv.y * 200) ;

        float  f = 5 * ( (sin(v.x) * 0.5 + 0.5) + (sin(v.y) * 0.5 + 0.5) );
        return fixed4(fixed3(0.1, 0.9, 1.0),  1-f);        
      }
      ENDCG
    }
  }
}

 
 

シェーダで水玉模様を作る原理

ここでは、ドットを打たないところ以外は透明にしたいのでBlendのタイプとQueue、Render Typeを指定しています。この辺は次のUnity Shaderの記事も参考にしてください。
 
nn-hokuson.hatenablog.com

重要なのはfragメソッドの中に書いているフラグメントシェーダです。少しややこしく見えるかもしれませんが、キモはsin(v.x)+sin(v.y)を計算しているところです。z = sin(x)+ sin(y)の計算結果は次のようになります。

f:id:nn_hokuson:20181001190113j:plain:w300

この山の高さを透明度にすることで頂上付近のみがドットとして表示されるという仕組みです。山の頂上だけをピックアップするからドットに見える、というのは上の図を横から見て考えたほうが分かりやすいかもしれません。

f:id:nn_hokuson:20181001185859p:plain:w400

Unityでシェーダを使って、その他の図形を書きたい場合は次の記事も参考にして下さい。

nn-hokuson.hatenablog.com

Prefabのシェーダを差し替える

シェーダができたところで、既存の平面検出シェーダと差し替えましょう。まずは今作成したシェーダをアタッチしたマテリアルを作成します。ARPlaneShaderを選択した状態で、右クリックして「Create」→「Material」を選択してください。

f:id:nn_hokuson:20181001190557p:plain:w200

このマテリアルをARKItの検出平面のPrefabに設定します。UnityARKitPlugin/Examples/Common/Prefabs/の中にあるdebugPlane→Planeオブジェクトのシェーダを今作成したCustom/ARPlaneShaderに変更してください。

f:id:nn_hokuson:20181001190801j:plain

これで、ビルドしてARKitを実行して平面を検出すると、次のように水玉模様が描かれた平面が検出されます。

f:id:nn_hokuson:20181001192028j:plain