おもちゃラボ

Unityで遊びを作っていきます

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

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

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

ARKitで画像トラッキングする流れは次のとおりです。

 

ARKitと画像トラッキング

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

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

nn-hokuson.hatenablog.com

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

ただ、残念なことに2018年10月現在、UnityからARKit Pluginを通してARImageTrackConfigurationを使用することができません。ここでは従来の手法を使って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

画像トラッキングの確認

これで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を使って次のようなサンプルを作っていきます。

f:id:nn_hokuson:20181008001126j:plain

「ARKit超入門」は下記のサイトから購入できます!
booth.pm
 

ARKit超入門の特徴

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

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

そこで、XcodeとSwiftを使ってネイティブ環境で開発することで短いサイクルで15個のアプリを開発できるように工夫しています。

3Dの表示にはSceneKitというAppleが開発したフレームワークを使用しています。初めての方でも簡単に理解できるように、必要な考え方は詳しく説明しています。

f:id:nn_hokuson:20181008001715j:plain

ARKit2.0にも対応

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

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

ARKit入門ではこれらの4つの機能についても詳しく説明しています。もちろんこれらの機能を使ったサンプルアプリケーションもついています!

f:id:nn_hokuson:20181008001729j:plain

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

ここでは次のようなアプリケーションを作成します。ダウンロードサイトには目次も載せているので、あわせてご覧ください!全128ページで販売価格は2000円になります。

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

ダウンロード

本書はPDFのダウンロード販売です。ダウンロードは次のはBOOTHのサイトからできます。

booth.pm

UnityではじめるARKit超入門 その4

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;
      }

      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