go back to article list page

AR名刺をつくった

はじめに

このブログは アイドルマスターミリオンライブ!のプロデューサーが集まった LIVE THEATER NET(通称LTN)というMisskeyインスタンスで企画された LIVE THE@TER NET Users' Advent Calendar 2023の12/16の投稿記事となります。なおLTNはアイドルマスターミリオンライブとは一切関係のない非公式のインスタンスです。

タイトルの通り、プロデューサー名刺をAR対応にしてみましたというお話になります。

あと中谷育ちゃん(と自分)の誕生日です。おめでとー。

完成品

こちらになります。

名刺(pdfです)

ARのページ

ARのスクリーンショット

動画はこちら

©窪岡俊之 THE IDOLM@STER™& ©Bandai Namco Entertainment Inc.

使用したもの

  • Blender ... ARでつかっているモデル部分(glbファイル)
  • AR.js Marker Training ... ARマーカーのパターンファイルと画像の作成

名刺自体はパワーポイントでサクッとつくっています

作成方針

ARをつかった名刺を実現する方法はいくつかあります。

  1. Unity + AR Foundationを使ったネイティブアプリ ... いちばんしっかり作る、結構カスタマイズしやすいが、iOSアプリのビルドがネック
  2. Unity + AR系SDKを使ったWebGL ... Unityの機能を使うことができる上に、web上で動作するのでプラットフォームを問わないのだが、SDKの利用料金がかかる
  3. AR.jsを使う ... javascriptで1から書く、モデルを別で用意しなくてはならないなど上2つよりハードルが高いが、その分AR体験までの障壁は少ない

上記3つのうち、名刺でQRコードを読んですぐ表示する、というのを達成するためにはAR.jsを使う方法が良いだろうと思い採用することにしました。

AR.js + A-frame

ただあんまり自分はAR.jsを使ったことがありません(今までつくったAR作品は全部Unity製)
調べると、A-frameというjavascriptで書かれた3D描画エンジンのようなものを使い、AR空間を表現することが可能とあるようなのでこれを使いました。

note: A-frameはWebGLでVRをするためのフレームワークです。
AR.jsにはA-frame用の拡張スクリプトがあり、これを使うとA-frame式のVR空間を現実に召喚することができます。

...もしかしてこれはAugmented Reality(AR)ではなくMixed Reality(MR)では?

AR.jsのA-frame拡張ではマーカーを設置する必要があります。AR.jsのデフォルトマーカーはいわゆるHiroマーカーというものですが、 AR.js Marker Trainingというサイトのものを使うことによって自作することができます。

名刺にはARを起動するためのURLのQRコードを貼り付ける予定でしたので、このQRコード画像自体をマーカーにすることにしました。

さて、3Dモデルはどうしよう?

マーカーを用意して、マーカーを読み込み、仮想空間を召喚する方法まではわかりました。ではその仮想空間をどうやって表現すればよいのでしょうか?

A-frameには様々なEntityを記述する方法があり、それで仮想空間を表現することはできます。ただ、これも非常に難しく時間がかかります。

そこで、Blenderを使いアニメーション付きのglbファイルを出力してこれをA-frameで使うことにしました。Blenderであれば3Dモデルが作りやすく、またアニメーションも細かく指定できるのでぐっとハードルが下がります。

note: glbファイルはWebGLで使うことができる3Dモデルのファイル形式です。
A-frameはWebGLを使っているため、当然このファイルを使うことができます。

Blenderでモリモリつくる

ということでサクッとモデルを作りました(3時間くらい?)

QRコードから魔法陣がでてきてにゅっとキャラクターがでるイメージです

blender_preview

これをBlenderのTopメニューから File>Export>glTF2.0 (.glb/.gltf) でエクスポートします

image

めちゃくちゃ簡単ですね

A-frame側で読み込んで終わり...とここで問題発生

A-frame自体にはアニメーション付きのglbファイルでアニメーションを再生する機能がありませんので、aframe-extras という拡張機能を使うことで再生することができます。

が、ここで大きな問題が発生します

読み込んだアニメーションは、再生し終えたあと再度マーカーが読み込まれても最初から再生されるわけではないということがわかったのです。
さらに、アニメーション自体はマーカーが読み込まれていない状態でも裏で再生されてしまうため、マーカーを読み込んだときにはすでに再生が終わってしまうという状況になってしまいました。

scriptでゴリ押す

残念ながら、entity自体にはマーカー読み込み時に再生・マーカーを見失ったら頭まで戻すという機能はないようでした。

そこで次のようなスクリプトを head に追加しました(headではなくbodyの一番下に入れると初期化後に実行されるのでうまくいかない)

<script>
    AFRAME.registerComponent('play-on-scan', {
        init: function () {
            var el = this.el;
            var animationEl = document.getElementById("animation-target");
            el.addEventListener('markerFound', function () {
                animationEl.setAttribute('animation-mixer', { clip: '*', loop: 'once', clampWhenFinished: true });
            });
            el.addEventListener('markerLost', function () {
                animationEl.removeAttribute('animation-mixer');
            });
        }
    });
</script>

ざっくり解説すると、 play-on-scanという名前の属性がついたエンティティで、初期化時に次のコードを実行してね。実行するコードはマーカー見つけたらアニメーション属性をつけて、見失ったら属性を外してねというスクリプトです。
a-marker には markerFoundmarkerLost というイベントがあり、このイベントにリスナーを追加することで達成できます。

再生後はその状態でとどまらせたいので clampWhenFinished を追加しています。
また、頭まで戻すためには再生するモデルのエンティティからanimation-mixerを外すことでできます。(と、色々調べたらでてきました)

完成

これでやっと当初の目的にそったARができました!完成ページはこちらになります

note: ちなみに、最初の頃はWebカメラがなぜかめちゃくちゃズームされた状態で表示されてしまう状態だったのですが、これはmetaタグのview-portでスケールを勝手にブラウザ側で設定できてしまうのが原因でした。
次のコードを入れることで解消できますので、もしこの現象に引っかかっている方はお試しください。
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />

さいごに

やり方さえわかってしまえば結構誰でも簡単に作れるのはめちゃくちゃ面白いです。流行れ!AR名刺!

CopyRights

©窪岡俊之 THE IDOLM@STER™& ©Bandai Namco Entertainment Inc.