Closed29

WebXR Depth Sensing Moduleについて調査

にー兄さんにー兄さん

いったん"depth-sensing"をrequiredFeaturesに入れて、scene.createDefaultXRExperienceしてみた

これにのっとって

すると、やはりdepthのセンシングをどうやるのか、どのフォーマットをサポートするのかを渡さないといけないらしい

にー兄さんにー兄さん

ごり押しでcreateDefaultXRExperience({})の中のuiOptionsに
depthSensingの情報を入れてみたが、うまくいかないみたい

理由はEnterXRの時点で、optionの情報がoptionalFeaturesとrequiredFeaturesだけに削られているからみたいだ

つまりcreatedefaultXRExperienceから有効化するのは無理っぽい

にー兄さんにー兄さん

enterXRを自分で呼び出す方法でも上記の問題が発生するのと、なぜかuserのアクティベーションが必要だよというエラーメッセージが表示される

にー兄さんにー兄さん

webxrFeatureManager.enableFeature()を使うことで、オプションと一緒にfeatureを有効化できる気がする
ただ、ここで有効化できるのはfeatureManagerにaddFeatureされたものであり、
featureはIWebXRFeatureをインターフェースを実装しているクラスである必要がある

つまりdepth sensingなどというfeatureはまだ実装されていないためenableできない

なのでWebXRDepthSensingというfeatureを実装するおkとにした

にー兄さんにー兄さん

本当にできるのかという疑問は残るが、実装さえすれば有効化できそうである

depthSensingディクショナリを追加してくれっていうエラーが出るということは、すくなくともdepthSensing系の実装が考慮されているということなので、これさえ乗り越えて有効化しさえすればなんとか動かせるのでは

にー兄さんにー兄さん

そういえば試しにこんな感じで書いてみる

するとこうなる

undefinedではない
Depth Sensingが有効であれば使えるなこれは

にー兄さんにー兄さん

ちなみにWebXR Incubationがdefaultでも同じ表記になったので、これは仏のChrome for ancroidでも使えそうな気配

にー兄さんにー兄さん

5時間くらい粘ったらBabylon.jsでWebXR Depth Sensing Moduleを有効にできた

にー兄さんにー兄さん

次のコードで実現可能、だが
ここまでの流れを見ればこれだけではできなきことはもうわかっている

にー兄さんにー兄さん

webxrEnterExitUI.jsの_enterXRWithButtonIndexのコードを直接編集している

ここはもともと、最後のoptionsは

{
  requiredFeature:this.options.requiredFeatures,
  optinalFeatures:this.options.optionalFeatres
}

といった具合になぜか絞り込みが行われていて、そのせいでdepthSensingオプションが省かれてしまっていたため、うまくdepth Sensingが有効にならなかったということだ

にー兄さんにー兄さん

これ、現状はcreateDefaultXRExperienceを使うから起きていると思うので、
XR系の初期化処理を自分で何とかすれば回避できるかもしれない

にー兄さんにー兄さん

現行のBabylon.jsではcreateDefaultXRExperienceを使うとdepth-sensingが使えないことが分かった
ということは逆にcreate~~でやっている処理の最後に呼び出されているenterXRAsyncを呼び出せばdepth-sensingを起動した状態でWebXRモードを起動できるよねという結論になって実装したコードが以下

  const xrHelper = await WebXRExperienceHelper.CreateAsync(this.scene);

  enterExitButton.onPointerDownObservable.add(() => {
    const handler = async (): Promise<void> => {
      // user activationのために待機
      await new Promise((resolve) => setTimeout(resolve, 100));
      await xrHelper.enterXRAsync('immersive-ar', 'unbounded', undefined, {
        requiredFeatures: ['depth-sensing'],
        depthSensing: {
          usagePreference: ['cpu-optimized'],
          dataFormatPreference: ['luminance-alpha'],
        },
      } as any);
    };
    handler().catch(null);

    enterExitButton.isVisible = false;
  });

  xrHelper.sessionManager.onXRSessionEnded.add(() => {
    enterExitButton.isVisible = true;
  });
にー兄さんにー兄さん

enterExitButtonはBabylonjs のGUIボタンであり、それを押すとXRモードに移行するんだけど、
WebXRモードの起動みたいな、全画面表示をするとかそういう
ユーザの操作性に関わる処理にはuser activationなるものが必要らしい

これはユーザが少なくとも1回以上は画面にタッチしたりインタラクションをした状態でないと
全画面モードに移行はできないよということらしい

これをクリアするために、ユーザのタッチイベントによってuser activationをさせてからWebXRモードに移行する必要があるため、待機してる

詳しくは以下
https://developer.mozilla.org/en-US/docs/Web/Security/User_activation

にー兄さんにー兄さん

サンプルに載っているコードを参考にすれば、距離の測定はすぐにできた

にー兄さんにー兄さん

やっぱりdepth推定だったらdepth画像表示したいよね......という欲があった
色々試行錯誤したので時間がかかったけど、なんとかリアルタイムでdepth画像を表示することに成功!!!
こういう画が欲しかったので満足です
https://www.youtube.com/watch?v=UVT9r38pV_A

にー兄さんにー兄さん

WebXRでdepth推定によるオクルージョンとか実現出来たらかなりアツいよねぇ~という感じではあるんだけど、
個人的に未来では、「オクルージョンとか普通でしょ?だってARオブジェクトが常に手前に表示されたらおかしいじゃん」みたいな世界観になってほしいね
そういう未来を作れるように一歩一歩着実に歩んでいかねば

このスクラップは2022/10/14にクローズされました