見出し画像

Niantic Lightship ARDK セマンティック セグメンテーションを使って空に映像を映し出す方法

おさらい

Niantic Lightship ARDK や セマンティック セグメンテーションについて、以下の記事でまとめております。

今回は...

セマンティック セグメンテーションの機能を使い、空に映像を映し出すサンプルアプリケーションを作成します。

1. Niantic Lightship ARDK ダウンロード

以下から入手してください。今回、使用しているバージョンはv1.1.0になります。入手する際、Niantic Lightshipのアカウント登録が必要です。

2. Niantic Lightship ARDK インポート

UnityEditor のメニューにあるAssets → Import Package → Custom Package...を選び、ダウンロードした ardk-1.1.0.unitypackage をインポートします。

3. 新規でSceneを作成とMain Cameraの削除

新規でSceneを作成後、Main Cameraを削除します。

4. ARSceneManagerをヒエラルキーに追加

スクリーンショット 2022-01-31 17.35.05

5. ARSceneManagerをUnpack Prefab Completely

スクリーンショット 2022-01-31 17.38.34

6. ARDepth Manager と ARSemanticSegmentationManager の追加

スクリーンショット 2022-01-31 17.41.24

ARSceneManagerの子コンポーネント、ARSceneCameraARDepthManagerARSemanticSegmentationManager のスクリプトを追加。

7. 動画素材の用意

以下の動画をダウンロードします。

https://www.pexels.com/ja-jp/video/854278/

スクリーンショット 2022-02-01 17.19.09

動画ファイルをAssets配下にドラッグ&ドロップ。(ここではVideoフォルダを作成し、Videoフォルダに動画ファイルを格納しています。)

8. 動画用のテクスチャ作成

動画用のテクスチャを作成します。Projectビュー内で 右クリック > Create > Render Texture で作成します。

スクリーンショット 2022-02-01 17.27.21

スクリーンショット 2022-02-01 17.37.21

ここではTextureというフォルダを作成し、作成したRender Textureを格納しています。また、Render Textureの名前をVideo Render Textureに変更しています。Sizeは動画サイズに合わせてます。Depth Bufferは無効にしています。

9. Video Playerの作成

ダウンロードしたビデオを作成するVideo Playerを作成します。

スクリーンショット 2022-02-01 17.58.47

Video PlayerのGame Objectを作成。Video Playerのコンポーネントを追加。Video Clipには動画ファイルを指定。Target Textureには作成したRender Textureを指定。ビデオ再生を繰り返したいためLoopにチェックを入れます。

10. 空のテクスチャ情報を動画のテクスチャに置き換えるためスクリプトを作成

Project上で右クリックでメニューを表示。Create→ C# Scriptを選択。スクリプトのファイル名をSemanticSampleとします。(ここではScriptというフォルダを作成を行い、フォルダにスクリプトを格納しています。)その後、以下のスクリプトに書き換えます。

using UnityEngine;
using Niantic.ARDK.AR;
using Niantic.ARDK.Extensions;
using Niantic.ARDK.AR.ARSessionEventArgs;
using Niantic.ARDK.AR.Awareness;
using Niantic.ARDK.AR.Awareness.Semantics;

public class SemanticSample : MonoBehaviour
{
   public Material _shaderMaterial;

   Texture2D _semanticTexture;

   public ARSemanticSegmentationManager _semanticManager;

   void Start()
   {
       _semanticManager.SemanticBufferUpdated += OnSemanticsBufferUpdated;
       ARSessionFactory.SessionInitialized += OnSessionInitialized;
   }

   private void OnSessionInitialized(AnyARSessionInitializedArgs args)
   {
       Resolution resolution = new Resolution();
       resolution.width = Screen.width;
       resolution.height = Screen.height;
       ARSessionFactory.SessionInitialized -= OnSessionInitialized;

   }

   private void OnSemanticsBufferUpdated(ContextAwarenessStreamUpdatedArgs<ISemanticBuffer> args)
   {

       ISemanticBuffer semanticBuffer = args.Sender.AwarenessBuffer;
       int channel = semanticBuffer.GetChannelIndex("sky");
       semanticBuffer.CreateOrUpdateTextureARGB32(
               ref _semanticTexture, channel
           );
   }

   void OnRenderImage(RenderTexture source, RenderTexture destination)
   {
       _shaderMaterial.SetTexture("_SemanticTex", _semanticTexture);
       _shaderMaterial.SetMatrix("_semanticTransform", _semanticManager.SemanticBufferProcessor.SamplerTransform);
       Graphics.Blit(source, destination, _shaderMaterial);
   }
}

スクリーンショット 2022-02-02 17.40.55

スクリプトはARSceneCameraに追加します。Semantic ManagerはARSceneCameraに追加したAR Semantic Segmentation Managerを指定。

11. 空のテクスチャ情報を動画のテクスチャに置き換えるためシェーダーを作成

Project上で右クリックでメニューを表示。Create→ Shaderを選択。Shaderで複数の形式がメニューで表示されますが、ひとまずStandard Surface Shaderを選択します。シェーダーをCustom/SemanticShとします。(ここではShaderというフォルダを作成を行い、フォルダにシェーダーを格納しています。)その後、以下のシェーダーに書き換えます。

Shader "Custom/SemanticSh"
{
   Properties
   {
       _MainTex ("Texture", 2D) = "white" {}
       _SemanticTex("_SemanticTex", 2D) = "red" {}
       _ReplaseTex("_ReplaceTex", 2D) = "white" {}
   }
   SubShader
   {
       // No culling or depth
       Cull Off ZWrite Off ZTest Always

       Pass
       {
           CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag

           #include "UnityCG.cginc"

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

           struct v2f
           {
               float2 uv : TEXCOORD0;
               float4 vertex : SV_POSITION;
               //storage for our transformed depth uv
               float3 semantic_uv : TEXCOORD1;
           };
           
           // Transforms used to sample the context awareness textures
           float4x4 _semanticTransform;
           
           v2f vert (appdata v)
           {
               v2f o;
               o.vertex = UnityObjectToClipPos(v.vertex);
               o.uv = v.uv;
               
               o.semantic_uv = mul(_semanticTransform, float4(v.uv, 1.0f, 1.0f)).xyz;
               return o;
           }

           //our texture samplers
           sampler2D _MainTex;
           sampler2D _SemanticTex;
           sampler2D _ReplaseTex;
           
           fixed4 frag (v2f i) : SV_Target
           {                
               //our semantic texture, we need to normalise the uv coords before using.
               float2 semanticUV = float2(i.semantic_uv.x / i.semantic_uv.z, i.semantic_uv.y / i.semantic_uv.z);
               //read the semantic texture pixel
               float4 semanticCol = tex2D(_SemanticTex, semanticUV);
               
               //unity scene
               float4 mainCol = tex2D(_MainTex, i.uv);
               float4 replaceCol = tex2D(_ReplaseTex, i.uv);
               float semanticRGBSum = semanticCol.r + semanticCol.g + semanticCol.b;
               return (semanticRGBSum == 3.0f) ? replaceCol : mainCol;
           }
           ENDCG
       }
   }
}

frag関数内でSemantic Segmentationのテクスチャカラーがホワイトの場合、検出されたテクスチャカラーとみなし、置き換え用のテクスチャカラーを返すようにしています。(置き換え用のテクスチャーは動画テクスチャーになります。)

12. 空のテクスチャ情報を動画のテクスチャに置き換えるためマテリアルを作成

Project上で右クリックでメニューを表示。Create→ Materialを選択。マテリアルの名前をVideo Materialとします。(ここではMaterialというフォルダを作成を行い、フォルダにマテリアルを格納しています。)

スクリーンショット 2022-02-02 18.33.11

Video Material の Shader に 先程、作成したCustom/SemanticShを選択します。Custom/SemanticShの_ReplaceTexに作成したVideo Render Textureを指定します。

13. スクリプトにマテリアルを指定

スクリーンショット 2022-02-02 18.39.53

ARSceneCameraに追加したSemanticSampleスクリプトのShader MaterialにVideo Materialを指定します。

14. ビルド&実行

スクリーンショット 2022-02-02 18.55.20

スマホのカメラを空にかざすと空をスクリーンになり、映像が流れます。

参考

最後に

OnePlanet XR

OnePlanet XR はAR/MR技術に専門特化したコンサルティングサービスです。豊富な実績を元に、AR/MR技術を活用した新たな事業の立ち上げ支援や、社内業務のデジタル化/DX推進など、貴社の必要とするイノベーションを実現いたします。

ご相談から受け付けております。ご興味ございましたら弊社までお問い合わせください。

OnePlanet Tech Magazine

様々な技術記事を定期的に投稿しています。