AndroidでAR〜ARCoreの導入から応用、
使う上での勘所まで
2018/5/9
高橋憲一
株式会社カブク / ソフトウェアエンジニア
高橋憲一
•携帯向け3Dグラフィクスエンジンや、昔あった某ARア
プリの開発に携わる
•現在はカブクで3Dグラフィクスのレンダリングおよび
解析エンジンの実装を担当
•個人的活動としてAR&VRの実験をする傍ら翻訳本を
出したり、技術系雑誌への解説記事を寄稿するなどし
ている
株式会社カブク / ソフトウェアエンジニア
@ken1_taka ktaka
翻訳した書籍
Daydreamの章を追加 TangoとARKitの章を追加
ARCore
今日話すこと
• ARCoreについておさらい
• ARCoreでできること(大きく分けて3つ)
• Google I/O 2018で発表された最新情報
• ARCoreの使い方
• サンプルをビルドしてみた後のその先へ
• ARCore 1.2の新機能を試してみる
ARCoreについておさらい
ARCoreとは
AndroidでARアプリを実現するためのGoogle純正ライブラリ
Android スケールで広く普及を目指す
ARCoreのこれまで
現在の最新版は 1.1.0 今日未明(JST) Google I/O 2018で1.2が発表されました!
対応機種も少し増えて、日本国内で普通に購入可能な端末もあります。
2018年3月30日 1.1.0 リリース
2018年2月24日 1.0.0 リリース
2017年8月29日 early preview リリース
対応機種
1.2.0でSony Xperia XZ1等が追加されました
最新の対応状況は
https://developers.google.com/ar/discover/supported-devices
ARCoreでできること
大きく分けて3つ
1. Motion tracking (モーショントラッキング)
https://developers.google.com/ar/discover/concepts CC BY 3.0
2. Environmental understanding(環境認識)
https://developers.google.com/ar/discover/concepts CC BY 3.0
平面の検出
水平面のみ水平と垂直の面を検出可能
(これまでは水平面のみだったものが1.2で垂直面も可能に)
Oriented Points(方向を持っている点)
平面として検出できるのは水平および垂直の面
ただし、
特徴点として検出した点の方向を取得することはできる
(特徴点が密集しているような場所だと検出しやすい)
周囲の条件が良ければこれくらいできます
3. Light estimation(光源推定)
https://developers.google.com/ar/discover/concepts CC BY 3.0
光源推定
光の強さを取得できる
光の当たる方向は取得できない
Google I/O 2018で発表された最新情報
Cloud Anchors
• 複数端末で同じAR空間を共有
できる
• 1つの端末からクラウドを通じて
他の端末に共有
• Anchorオブジェクト
• 周辺の特徴点
• AndroidだけでなくiOSとも共
有可能
• iOS用にもSDKが提供される
Augmented Images
• 指定した画像を認識して、位置と姿
勢をトラッキングする
ARCoreの使い方
ARCoreのapkをインストール
アプリ本体の他にARCoreを対応端末にインストール
する必要があります
開発方法
開発は
• Java
• C++ (NDK)
• Unity
• Unreal Engine
• Web
の何れでも可能
ビルド環境の設定
推奨されるUnityのバージョン: Unity 2017.4 LTS以降
前提: 新規プロジェクトを作成し、Androidのアプリをビルド可能な状態
ARCore SDK for UnityをダウンロードしてUnityにインポートする
https://github.com/google-ar/arcore-unity-sdk/releases/download/v1.1.0/
arcore-unity-sdk-v1.1.0.unitypackage
Android Player Settings → Other Settings
• Multithreaded Rendering をオフ
• Minimum API Level を Android 7.0 以上にする
• Target API Level は Automatic
Android Player Settings → XR Settings
• ARCore Supportedをオンにする
サンプル “HelloAR”
SDKに付属するサンプルは
Assets/GoogleARCore/Examples/HelloAR
にあります
Instant Preview
ビルドして端末に転送すれば実行できますが、
Unityのエディタ上でプレビューも可能です
手順は対応端末をつないでPlayボタンを押すだけ
端末にInstant Previewアプリが転送されてプレビューできます
Unity用のAPIについて
https://developers.google.com/ar/
reference/unity/
にリファレンスがあります
機能毎に使っているAPIを見てみる
認識した平面上の位置の取得
TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
TrackableHitFlags.FeaturePointWithSurfaceNormal;
Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit)
画面をタップした位置(touch.position)からレイを延ばした先にぶつかる平面、もしくは
Oriented Pointを検出します
raycastFilterには平面とOriented Pointの両方を検出するための値を設定しています
検出した情報は hit に入ってきます
取得した位置に3Dオブジェクトを配置する
var andyObject = Instantiate(AndyAndroidPrefab, hit.Pose.position, hit.Pose.rotation);
前ページで検出した hit の Pose の位置と姿勢を使って、設定したプレハブのモデルを
Instantiate で実体化します
サンプルをビルドしてみた後のその先へ
サンプルに3Dプリント風エフェクトを組み込む
指定したY座標のX-Z平面でクリッピングするシェーダーの記述と、そのY座標の値をフレー
ムごとに移動させるスクリプトを組み合わせることで実現
シェーダーの修正
サンプルに含まれる
 ARCore/DiffuseWithLightEstimation
というシェーダーをコピーして編集します。
(シェーダーのフォルダ
Assets/GoogleARCore/Examples/HelloARの下のMaterials/Shaders)
シェーダーのプロパティ
_ConstructY … クリッピングするY座標の値
_ConstructGap … 積層していく際に色を変える境界の高さ
_ConstructColor … 積層していく際の境界の色
void surf (Input IN, inout SurfaceOutput o)の中身-1
if(IN.worldPos.y > _ConstructY + _ConstructGap)
{
discard;
}
描画されないようクリッピングする処理です。
ピクセルのワールド位置のY座標の値が「クリッピングするY座標 + 境界の高さ」より大き
い(クリッピングする位置より高い位置にある)場合、discardして描画しないようにします。
void surf (Input IN, inout SurfaceOutput o)の中身-2
if(IN.worldPos.y < _ConstructY)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
} else {
o.Albedo = _ConstructColor.rgb;
o.Alpha = _ConstructColor.a;
}
ピクセルのワールド位置のY座標の値がクリッピングするY座標より小さい場合、通常描画
の対象としてテクスチャからの色を反映します。Y座標の値以上の場合、境界部分の描画
対象として境界の色を反映します。
スクリプトの追加
エフェクトをかけたいモデルのメッシュを保持するオブジェクトに
スクリプトを追加します(Andyの場合はAndy_GEO)
Start()メソッドの中身-1
Renderer renderer = GetComponent<Renderer> ();
material = renderer.material;
このスクリプトが関連づけられたオブジェクトのマテリアルを複製して保持します
マテリアルに設定したシェーダーのプロパティ(クリッピング位置のY座標)を操作するた
め、そのままでは複数のオブジェクトを表示した場合すべて連動してしまいます(既に表示
済みのオブジェクトに対してもエフェクトがかけられることを防ぐため)
Start()メソッドの中身-2
var mesh = GetComponent<MeshFilter> ().mesh;
var bounds = mesh.bounds;
clipY = minY = bounds.min.y + transform.position.y;
maxY = bounds.max.y * 1.2f + transform.position.y;
オブジェクトのバウンディングボックスのサイズを取得し、Y座標の変化の範囲として接地
面(最小値)から頭のてっぺん(最大値)までを設定します
注意する必要があるのは、接地面であるARCoreで取得した平面のY座標(高さ方向)です
接地面はのY座標は0の前提で考えることも多いかもしれませんが、ここでは最小値と最大
値にワールド空間でのY方向のオフセット値(transform.position.y、positionはタップし
てオブジェクトが配置される際に与えられます)を加えることで高さを合わせてあります
Update()メソッドの中身
if (clipY < maxY) {
clipY = Mathf.Lerp (minY, maxY, (Time.time - startTime) / duration);
material.SetFloat ("_ConstructY", clipY);
}
線形補間関数(Mathf.Lerp)を使ってクリッピング位置の最小値から最大値の間の経過
時間に応じた値を求め、シェーダーに渡します
clipY < maxYという条件を入れて、最大値(頭のてっぺん)に到達したらそれ以降クリップ
するY座標値は変化しないようにします
3Dプリント風エフェクトの解説
https://www.kabuku.co.jp/developers/ar3d_print
にさらに詳しい解説があります
ARCore 1.2の新機能を試してみる
ARCore 1.2のapkをインストール
Google Play StoreにあるARCoreは
まだ1.2が行き渡っていないため、しばらくは(数日?)
https://developers.google.com/ar/develop/downloads
から ARCore_1_2.apk をダウンロードして手動インストール
する必要があります
$ adb install -r -d ARCore_1_2.apk
ビルド環境の設定
推奨されるUnityのバージョン: Unity 2017.4 LTS以降
前提: 新規プロジェクトを作成し、Androidのアプリをビルド可能な状態
ARCore SDK for Unityの1.2をダウンロードしてUnityにインポートする
https://github.com/google-ar/arcore-unity-sdk/releases/download/v1.2.0/
arcore-unity-sdk-v1.2.0.unitypackage
Augmented Images
Assets/GoogleARCore/Examples/
AugmentedImage/Images
にサンプルがあります
その他
Poly
主にARとVRでの活用を目的とした
3Dモデル共有サイト
CC-BYで使用できるものが多い
Google I/OのAR&VR関連セッション
AR & VR関連で9つのセッションがあります。
https://events.google.com/io/schedule?
section=may-8&topic=ar%26vr&type=ses
sions
(どれも動画が公開されます)
Codelabの紹介
詳細な手順で解説されているので、実際に手を動かしながら進めることができます
https://codelabs.developers.google.com/?cat=Augmented+Reality
日本語で質問、相談できるフォーラム
http://bit.ly/vrar_ja
ぜひご登録ください!
日本語で気軽に質問、相談
できるように立ててみました
Googleアカウントがあれば
何方でも参加可能です
Thank you!
ご静聴ありがとうございました!

【Unite 2018 Tokyo】AndroidでAR〜ARCoreの導入から応用、使う上での勘所まで