tpc22-2

TOPIC 22|3D都市モデルと位置情報をUnityで扱う[2/2]|ARアプリにまとめる

ここからは、表示してきたさまざまな位置情報を、実際のARアプリとしてまとめます。

Share

ここからは、表示してきたさまざまな位置情報を、実際のARアプリとしてまとめます。

【目次】

22.4    ARアプリの開発

22.5   AR Foundation・Geospatial APIの設定

22.6   アプリ完成

ARアプリの完成図

22.4 _ ARアプリの開発

ここでは、①あらかじめアプリに内蔵した位置情報をAR表示する機能、②新しい位置情報を端末のGPSから記録してAR表示する機能、③3D都市モデルを表示する機能、という3つの機能を持ったARアプリを作成します。

ARで見やすいように、3D都市モデルの表示を工夫します。

◾️半透明シェーダー

今回は、完全に透明なオクルージョンではなく、3D都市モデルが半透明で見えるようなマテリアルを作成します。ただ単に半透明で表示すると、建築物同士の重なりが多い部分が白飛びして見えにくくなるので、深度を考慮した半透明のシェーダーを書きます。

こうしたシェーダーは、まず深度バッファのみ更新し、その上に深度バッファを検証しながら半透明で描画する2パスのシェーダーとして作ります。

今回のプロジェクトはURPなので、URPに対応したシェーダーを書きます(リスト22-8)。

また、このシェーダーを使うマテリアルを作成します。Colorには、任意の色を設定してください。画面では灰色にしています。

Shader "Custom/Building"
{
    Properties
    {
        _Color("Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
        LOD 200


        Pass {
            Tags {"LightMode" = "SRPDefaultUnlit"}
            ZWrite On
            ColorMask 0
        }


        Pass
        {
            Tags {"LightMode" = "UniversalForward"}
            Tags{ "QUEUE" = "Transparent" "IGNOREPROJECTOR" = "true" "RenderType" = "Transparent" }
            Blend SrcAlpha OneMinusSrcAlpha
            ColorMask RGBA
            ZWrite Off
            ZTest LEqual


            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            #include "UnityCG.cginc"


            fixed4 _Color;


            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };


            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD0;
            };


            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }


            fixed4 frag(v2f i) : SV_Target
            {
                float3 L = normalize(_WorldSpaceLightPos0.xyz);
                float3 N = normalize(i.worldNormal);
                fixed4 col = _Color * max(0, dot(N, L) * 0.5f + (1 - 0.5f));
                return col;
            }
            ENDCG
        }
    }
}

リスト22-8 深度を考慮した半透明のシェーダー

図 22-30 シェーダーを使うマテリアル

◾️メッシュをまとめる

このシェーダーは、ひとつのメッシュでしか有効ではありません。2パスで描画する際、メッシュひとつごとに2つのパスが交互に実行されるため、そのメッシュ内では背後が隠れますが、他のメッシュで描画したものは透過してしまうためです。

もともとの3D都市モデルは、区画ごとにメッシュが分割されています。つまり、複数の区間を読み込んだ場合は、この制限に引っかかります。そこで、全体をひとつのメッシュにまとめてしまいましょう。

メッシュをまとめるやり方はいくつかありますが、ここでは、Unityのアセットストアから、Mesh Combinerをインストールして使います。アセットストアで入手したら、Package Managerからインストールしてください。

【Mesh Combiner】

https://assetstore.unity.com/packages/tools/modeling/mesh-combiner-157192

読み込んだ3D都市モデルのGameObjectにMesh Combinerスクリプトをアタッチし、図のような設定にして「Combine Meshes」ボタンを押すと、すべてのメッシュがひとつにまとまります。このとき子についている「53394588_bldg_6697_2_op.gml」などのオブジェクトはDisableにするか、消すなどしておきます。

図 22-31 Mesh Combinerで、すべてのメッシュをひとつにまとめる

これでメッシュが統合され、先ほどのマテリアルを設定することで、半透明だけれども背後は描画されないという意図した見え方になります。

図 22-32 半透明で背後が描画されなくなった
コラム:メッシュ統合の際の注意

メッシュをまとめると、Game Objectの階層構造が削減したり、Draw Callが削減して描画が効率化したりするので、ほとんどの場合、パフォーマンスが向上します。

しかし、広大な範囲のメッシュをまとめてしまうと、まとめる前は表示されないと判断されて描画していなかった部分の計算がまとめてしまったために判定しなければならなくなり、場合によってはパフォーマンスが悪化します。あまりにも広大な範囲のメッシュをまとめるときは気をつけてください。

22.5 _ AR Foundation・Geospatial APIの設定

次に、AR FoundationとGeospatial APIを導入します。詳細については、TOPIC14 「VR・ARでの活用[3/3]|Google Geospatial APIで位置情報による3D都市モデルのARを作成する」も参考にしてください。

【手順】AR FoundationとGeospatial APIの導入

[1]パッケージを追加する

[Window]メニューから[Package Manager]を開きます。左上の[+]をクリックし、[Add package from git URL]を選択します。そして次のURLを貼り付け、[Add]をクリックします。

https://github.com/google-ar/arcore-unity-extensions.git 

ARCore Extensionsの追加画面が表示されたら、[Samples]の項目にある[Geospatial Sample]の[Import]をクリックして、このサンプルもインポートしておいてください。

ARCore Extensionsをインストールすると、設定したビルドプラットフォームに応じて、必要な依存関係の拡張も合わせてインストールされます。

図 22-33 パッケージを追加する

[2]環境設定する

[Edit]メニューから[Project Settings]を開き、いくつかの設定を加えます。

【Androidの場合】

ARCoreにチェックを付けて、有効化します。

図 22-34 ARCoreを有効化する(Androidの場合)

【iOSの場合】

ARKitにチェックを付けて、有効化します。

図 22-35 ARKitを有効化する(iOSの場合)

さらに、[ARCore Extensions]の項目で、APIキーを設定します(Android、iOSとも)。APIキーは、Google Cloudのコンソールで作成したものを設定します。

図 22-36 APIキーの設定

[3]ビルドの設定

[Player]タブで、AndroidもしくはiOSの各プラットフォームのビルドについて、次のように設定します。

【Androidの場合】

・Minimum API Levelは、28程度が妥当です。

・IL2CPPでビルドします。

・Graphics APIは、OpenGL ES3以上が必要です。

【iOSの場合】

・サポートするOSは、iOS11以上です。

・ARM64でビルドします。

またURPの設定で、Renderer FeaturesにAR Background Renderer Featureが設定されていない場合、追加してください。

図 22-37 [AR Background Renderer Feature]を追加する

[4]サンプルを改造する

Package Managerでインポートしたサンプルは、[hierarchy]ウィンドウの[Assets]―[Samples]から確認できます。

Geospatial APIのサンプルの中から、Geospatialシーンを開き、これまで作ってきたシーン内の、3D都市モデルとデータの読み込みのオブジェクトなどをコピーします。

22.6 _ アプリ完成

ビルドして端末で実行すると、いくつかの3Dオブジェクトが現実のカメラ画像に重なって表示されます。赤色の円柱で表示されている場所が、CSVファイルとして用意した地点です。サンプルとして4か所のレストランの場所が表示されています。緑色の円柱がオープンデータとして取り込んだバス停の場所です。バス停の名称が上空に表示されています。また、「Place」ボタンを押すと、端末のGPSで取得したその時点の場所を青い円柱で表します。さらに、GPS受信機のNMEAデータから読み込んだ軌跡が表示されています。

図 22-38 アプリ実行画面

【文】

於保俊(株式会社ホロラボ)

【協力】

大澤文孝