ウェブ向けの拡張現実(AR)

Joe Medley
Joe Medley

Chrome 67 では、拡張現実(AR)とバーチャル リアリティ(VR)の両方に対応した WebXR Device API を発表しましたが、VR 機能のみが有効になっていました。VR はコンピューティングデバイスの 内容のみに基づくエクスペリエンスです一方、AR では、現実世界に仮想オブジェクトをレンダリングできます。これらのオブジェクトの配置とトラッキングを可能にするため、Chrome Canary に WebXR Hit Test API を追加しました。これは、没入型ウェブコードでオブジェクトを現実世界に配置するための新しい方法です。

どこで入手できますか?

この API は当面は Canary での利用を想定しています。これは非常に新しい API プロポーザルであり、デベロッパーにとって堅牢で適切なものであることを確認するため、テスト期間を長くしています。

Chrome Canary のほかに、次のものが必要です。

これらの機能を使って、デモを試したり、Codelab を試したりできます。

ウェブのみ

今年の Google IO では、Chrome の初期ビルドで拡張現実のデモを行いました。3 日間、デベロッパーとデベロッパー以外の人々に繰り返し伝えたことがあります。それは、没入型ウェブに関する記事に記載しておけばよかったと思うことです。「ウェブに過ぎない」ということです。

「どの Chrome 拡張機能をインストールすればよいですか?」「延長はできません。ウェブなのです。」

「特別なブラウザが必要ですか?」「ウェブだけです。」

「どのアプリをインストールする必要がありますか?」「特別なアプリはありません。ウェブのみです。」

ウェブに特化したウェブサイトでこの記事を読んでいる方にとっては、これは当たり前のことかもしれません。この新しい API でデモを作成する場合は、この質問の準備をしてください。よく聞かれます。

IO について言えば、没入型ウェブ全般、その現状、今後の展望について詳しくは、こちらの動画をご覧ください。

利点

拡張現実は、既存の多くのウェブページに価値ある追加機能となります。たとえば、教育サイトでユーザーが学習したり、購入を検討しているユーザーがショッピング中に家の中にオブジェクトを視覚化したりできます。

デモでこのことを説明します。実物大のオブジェクトを本物のように配置できます。配置した画像は、選択したサーフェスに留まり、実際のアイテムがそのサーフェスにある場合と同じサイズで表示されます。ユーザーは画像を移動したり、画像に近づいたり離れたりできます。これにより、2 次元画像では不可能な、オブジェクトのより深い理解を視聴者に提供できます。

これらの意味がわからない場合は、デモを使用するとわかります。デモを実行できるデバイスがない場合は、この記事の上部にある動画リンクをご覧ください。

デモや動画で示されていないことの一つは、AR が実際の物体の大きさをどのように伝えるかということです。この動画は、Google が作成した教育用デモ「Chacmool」を示しています。このデモについて詳しくは、こちらの記事をご覧ください。この議論で重要なのは、拡張現実にチャコール像を配置すると、その大きさが実際に目の前の部屋にいるかのように見えるということです。

Chacmool の例は教育用ですが、商用にも使用できます。リビングルームにソファを配置できる家具ショッピング サイトがあるとします。AR アプリでは、ソファが部屋に収まるかどうかや、他の家具の横に置いた場合の様子を確認できます。

レイキャスト、ヒットテスト、レチクル

拡張現実を実装する際に解決すべき重要な問題は、オブジェクトを現実世界ビューに配置する方法です。この方法は「レイキャスト」と呼ばれます。レイキャストとは、ポインタ レイと現実世界のサーフェスとの交差点を計算することを意味します。この交差点は「ヒット」と呼ばれ、ヒットが発生したかどうかを判断することを「ヒットテスト」と呼びます。

この機会に、Chrome Canary で新しいコードサンプルをお試しください。何かする前に、適切なフラグが有効になっていることを再確認してください。サンプルを読み込み、[AR を開始] をクリックします。

次の点に注意してください。まず、他の没入型サンプルで見慣れたスピードメーターは、60 ではなく 30 フレーム / 秒を示しています。これは、ウェブページがカメラから画像を受信するレートです。

AR は 30 フレーム/秒で動作します

AR ヒットテストのデモ

もう一つ注目すべきは、ヒマワリの画像です。移動すると移動し、床や天板などの表面にスナップされます。画面をタップすると、ヒマワリがサーフェスに配置され、新しいヒマワリがデバイスとともに移動します。

デバイスとともに移動し、サーフェスにロックしようとする画像をレチクルと呼びます。レチクルは、拡張現実にオブジェクトを配置する際に役立つ一時的な画像です。このデモでは、レチクルは配置する画像のコピーです。しかし、必ずしもそうである必要はありません。たとえば、Chacmool のデモでは、配置されるオブジェクトのベースとほぼ同じ形状の長方形のボックスです。

コードレベル

Chacmool デモは、本番環境のアプリで AR がどのように表示されるかを示しています。幸い、WebXR サンプル リポジトリには、よりシンプルなデモがあります。サンプルコードは、そのリポジトリの AR ヒットテストデモから取得しました。なお、何が起こっているのかを理解していただくため、コード例を簡素化しています。

AR セッションへのエントリとレンダリング ループの実行の基本は、VR の場合と同じです。詳しくは、こちらの記事をご覧ください。具体的には、AR セッションの開始と実行は、VR マジック ウィンドウ セッションの開始とほぼ同じです。マジック ウィンドウと同様に、セッション タイプは没入型ではなく、参照型のフレームは 'eye-level' である必要があります。

新しい API

次に、新しい API の使用方法について説明します。AR では、レチクルはアイテムを配置する前にサーフェスを見つけようとします。これはヒットテストで確認できます。ヒットテストを行うには、XRSession.requestHitTest() を呼び出します。たとえば、次のようになります。

xrSession.requestHitTest(origin, direction, frameOfReference)
.then(xrHitResult => {
  //
});

このメソッドの 3 つの引数は、レイキャストを表します。レイキャストには、レイ上の 2 つのポイント(origindirection)と、それらのポイントが計算される場所(frameOfReference)を指定します。起点と方向はどちらも 3D ベクトルです。送信する値に関係なく、長さが 1 に正規化(変換)されます。

レチクルを移動する

デバイスを動かすと、オブジェクトを配置できる場所を探すために、レチクルも動く必要があります。つまり、レチクルはフレームごとに再描画する必要があります。

requestAnimationFrame() コールバックから始めます。VR と同様に、セッションとポーズが必要です。

function onXRFrame(t, frame) {
  let xrSession = frame.session;
  // The frame of reference, which was set elsewhere, is 'eye-level'.
  // See onSessionStarted() ins the sample code for details.
  let xrPose = frame.getDevicePose(xrFrameOfRef);
  if (xrPose && xrPose.poseModelMatrix) {
    // Do the hit test and draw the reticle.
  }
}

セッションとポーズが決まったら、光線がキャストされている場所を特定します。サンプルコードではgl-matrix 数学ライブラリを使用しています。ただし、gl-matrix は必須ではありません。重要なのは、何を計算しているか、デバイスの位置に基づいていることを把握することです。XRPose.poseModalMatrix からデバイスの位置情報を取得します。レイキャストを手に、requestHitTest() を呼び出します。

function onXRFrame(t, frame) {
  let xrSession = frame.session;
  // The frame of reference, which was set elsewhere, is 'eye-level'.
  // See onSessionStarted() ins the sample code for details.
  let xrPose = frame.getDevicePose(xrFrameOfRef);
  if (xrPose && xrPose.poseModelMatrix) {
    // Calculate the origin and direction for the raycast.
    xrSession.requestHitTest(rayOrigin, rayDirection, xrFrameOfRef)
    .then((results) => {
      if (results.length) {
        // Draw for each view.
      }
    });
  }
  session.requestAnimationFrame(onXRFrame);
}

ヒットテストのサンプルではそれほど目立ちませんが、シーンを描画するにはビューをループする必要があります。描画は WebGL API を使用して行われます。非常に意欲的な場合は、ただし、フレームワークを使用することをおすすめします。没入型ウェブのサンプルでは、デモ専用に作成された Cottontail を使用しています。Three.js は 5 月から WebXR をサポートしています。

オブジェクトの配置

ユーザーが画面をタップすると、オブジェクトが AR に配置されます。そのためには、select イベントを使用します。このステップで重要なのは、デバイスを配置する場所を把握することです。動くレチクルは常にヒットテストのソースとなるため、オブジェクトを配置する最も簡単な方法は、最後のヒットテストでレチクルがあった位置にオブジェクトを描画することです。レチクルを表示しない正当な理由がある場合、サンプルに示すように、select イベントで requestHitTest() を呼び出すことができます。

まとめ

これを理解するには、サンプルコードをステップ実行するか、Codelab を試してみることをおすすめします。両方の背景を十分に理解していただけたでしょうか。

没入型ウェブ API の開発は、まだ始まったばかりです。進捗状況に応じて、新しい記事を公開します。