Occlusionを試しました。実装方法にたどり着くまでに結構遠回りしたので、知見として共有しておきます。3の新機能の1つとして公開されたもので、カメラ映像から人を検出してオクルージョンを行うことができます。従来のARでは、カメラに映り込んだ人は常にコンテンツの全面に表示されてしまうため、不自然な表示になっていました。Occlusionを行うことで手前にいる人にコンテンツが隠れ、前後関係が正しく見えるようになります。2019今まで実装が難しかった"人とAR空間"、"人とバーチャルキャラクター"がコラボする映像表現がやりやすくなります。Foundationを使って実装してもARKitの一部デバイスのみで利用できる機能になります。X以前のデバイスでも使えません。詳細は以下のページにまとめています。11に機種変更しました。Developerにサンプルコードがあり、すぐに試すことができます。Foundationにはそのものズバリのサンプルがまだ無いので、先にこちらを動かしておくと機能がイメージしやすくなります。Renderersリンク先から"DOWNLOAD"を行うと、Xcodeプロジェクトを含んだzipファイルが取得でき、以下の手順ですぐに実機で試せます。Licenseのようです。Inc.)の著作権表示さえ行えば、サンプルコードを利用・改変してアプリを作っても問題はありません。2.2.x以上が必要です。3.0が公開されているため、こちらを試してみることにします。Samplesのサンプルを動かして、ソースコードを読むのが定石です。Licenseで提供されており、本サンプルを改変して開発したアプリの公開も可能です。Appのサンプルと異なり、オクルージョン処理は実装されていません。前提知識を頭に入れて理解を深めるには良いので一度動かしてみましょう。HumanStencilを表示するHumanSegmentationImagesをそのままビルドして実機で動かすと以下のような結果になります。画面左上にカメラ映像とは別のイメージが表示され、人が写っている部分が赤くなっています。これはARHumanBodyManagerから取得できるhumanStencilTextureになります。取得方法は後述します。b:0)の二値画像になっています。Resolutionが設定されています。Managerがアタッチされています。Info)を更新しているようです。TestDepthImage.csで行われている処理は複雑ではなく、humanStencilTextureの取得部分は以下で実装できます。humanStencil;}HumanDepthを表示するHumanSegmentationImagesでは、スクリプトでhumanDepthTextureも取得していますが、画面にはhumanStencilTextureしか表示していません。TestDepthImage.csの末尾でコメントアウトされている処理を修正すると表示できます。humanStencilがセットされています。humanDepth;のコメントアウトを外します。eventArgsはundefinedになってしまうため、コメント内のBugと思われます。humanDepth;上記の修正を行なってビルド・実行すると以下のようになります。一見すると同じようにも見えますが、赤く表示された部分に明暗が付いた距離画像になっています。b:0)に近い色になることがわかります。rの値がカメラからの距離を表しており、値が小さいほど距離が近く、値が大きいと距離が遠いことを示しています。Occlusionを実装するHumanStencil、HumanDepthが取得できることがわかったので、人の有無とその距離に応じて、ARコンテンツを描画するかどうかを決めればよいことになります。実装方法としては、シェーダーを利用したポストエフェクトが有力です。Forumで議論がなされており、サンプルコードも共有されているので、そちらを参考に実装していくのが最短だと思います。Forumのサンプルと同じ内容ですが、動作が確認できたShaderとC#スクリプトをgistに登録しましたので、参考にしてみてください。Cameraにコンポーネントとして追加します。このスクリプトにPeopleOcclusion.shaderをアタッチすれば、ポストエフェクトがかかります。実行結果シェーダーの動作を理解するとりあえず、やりたいことはできました。やったね!なのですが、ここで終わると応用が効かないので、頑張ってシェーダーを読みましょう。重要なフラグメントシェーダーがこちら。showOccluder);}1行ずつ読み解いていきます。i.uv);colにはポストエフェクトをかける前のテクスチャがセットされています。i.uv1);cameraFeedColにはスクリプトのARCameraManagerで取得したカメラ映像が入っています。i.uv));sceneDepthはUnityでシーンに配置したカメラから取得できるARシーンのデプステクスチャです。i.uv2);stencilColにはスクリプトで取得したHumanStencilが入っています。observationocclusionDepthにはスクリプトで取得したHumanDepthが入っています。HumanDepthは0から1の値で深度を表していましたが、そこに現実空間と距離を合わせるための係数として0.625をかけています。stencil)showOccluderがこのシェーダーのポイントとなる値です。yなら0となる関数です。0:人がオブジェクトの後方にいるとなります。上記に対して、さらにstencilCol.rをかけています。occlusionDepthは人を検知していないPixelにもr=0が入ります。1となってしまい、人がいない場所なのにオクルージョンの対象となってしまいます。一方のstencilCol.rは人を検知したPixelのみ1になるので、確実に人がいる場所のみ値が取れます。整理すると、以下のようになります。0:人が検知されていない、もしくはオブジェクトの後方にいる試しに表示してみると、人が検知されている場所のみ白(1)、他が黒(0)になっていることがわかります。showOccluder);最後にreturnの値です。s)はsの値に応じて線形補間を行う関数です。sが0のときにx、1に近づくにつれてyになります。DocssはshowOccluderなので、前述の通り、0か1です。0のときはオブジェクトの手前には人がいないため、colをそのまま描画します。1のときは手前に人がいることになるのでカメラ映像のcameraFeedColで上書きしています。することで、人が手前にいる場合はカメラ映像に映った人が優先して描画され、結果としてオブジェクトが人の後ろに回り込む形になります。yがcameraFeedColとなっていますが、この値を変えることで人が存在する部分にポストエフェクトをかけることもできます。この用途で使う場合、デプスの比較をせずにsをstencilCol.rとしても良さそうです。Occlusionを実装するTweetiOS/Android対応のARアプリを公開しています。Occlusionを実装する月別アーカイブBOOTHBOOTHで技術書売ってます。jyuko49はてなブログをはじめよう!jyuko49さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。