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

ジョー・メドレー
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 について言えば、没入型ウェブ全般や場所、利用場所についてはこちらの動画をご覧ください。

用途

拡張現実は、既存の多くのウェブページに追加する価値があるでしょう。たとえば、教育関連のサイトで学習できるようにし、購入を考えている人は購入の際に自宅の物体を可視化できます。

Google のデモでこれを確認できます。ユーザーはオブジェクトを 実物のようにリアルサイズで表現できます配置すると、画像は選択したサーフェスに固定され、実際のアイテムがそのサーフェス上にあった場合のサイズで表示されます。また、ユーザーは画像の周囲に移動したり、近づけたり遠ざけたりできます。これにより、閲覧者は 2 次元の画像よりもオブジェクトをより深く理解できます。

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

デモや動画では示されていないものの、AR では実際の物体の大きさをどう表現できるかということは明らかではありません。こちらの動画では、Google が作成した Chacmool という教育用デモを紹介しています。このデモについて詳しくは、コンパニオンの記事をご覧ください。この説明で重要なのは、拡張現実で Chacmool 像を配置すると、まるで自分の部屋の中にいるかのようにサイズが表示されることです。

Chacmool の例は教育的ですが、同じくらい簡単に商業的になりえます。リビングルームにソファを置くことができる家具販売店を想像してください。AR アプリケーションを使用すると、そのソファが自分のスペースに合うかどうか、他の家具と並べてどのように見えるかがわかります。

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

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

ここで Chrome Canary の新しいコードサンプルを試すことをおすすめします。なんらかの操作を行う前に、正しいフラグが有効になっていることを再度確認してください。サンプルを読み込み、[Start AR] をクリックします。

以下の点にご注意ください。まず、他の没入型サンプルで認識できる速度メーターは 60 フレーム/秒ではなく 30 フレーム/秒です。これは、ウェブページがカメラから画像を受信する速度です。

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

AR ヒットテストのデモ

注目すべきはヒマワリの画像です。動かすと移動し、床やテーブルトップなどの表面にスナップします。画面をタップすると、ヒマワリが表面に置かれ、新しいヒマワリがデバイスと一緒に動きます。

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

コードを確認する

Chacmool デモは、本番環境のアプリで AR がどのように見えるかを示しています。幸いなことに、WebXR サンプル リポジトリではるかにシンプルなデモが公開されています。サンプルコードは、このリポジトリの AR ヒットテストデモからのものです。参考のために、コードサンプルは簡略化されています

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 を試してみることをおすすめします。両方を理解するのに十分な背景情報が得られました。

Google は、臨場感あふれるウェブ API の構築を終えたわけではありません。進展があり次第、こちらで新しい記事を公開してまいります。