はじめに
「オリジナルの3DモデルがARで簡単に表示できたら何かに使えそう!」
ということで、簡単に実装できる方法はないか探して実践してみました。
WebAR とは?
「Webブラウザ上でARが体験できる仕組み」 です。
以下のメリットがあります。とにかく手軽さ・簡単さが大きな特徴!
- アプリのインストールが必要ない
- URLをシェアするだけで簡単に共有できる
- ライブラリや作成ツールが充実していて手軽に作成できる
実装に使用したもの
以下のフレームワークとライブラリを使うことで簡単に作成できます。
- A-Frame
- https://aframe.io/
- Web 上で 3D コンテンツや VR 体験を簡単に作成できるフレームワーク
- マークアップ言語(HTMLなど)を使って 3D オブジェクトやシーンを作成できる
- AR.js
- https://ar-js-org.github.io/AR.js-Docs/
- Web 上で AR 体験を実現するためのライブラリ
- A-Frame と組み合わせることで、Web ブラウザを通じて簡単に AR コンテンツを作成できる
それぞれの役目としては、
「A-Frameで、HTMLタグによるシーン構築・3Dモデル・カメラの動き等を容易にコントロールし、AR.jsで、ARに特化した体験(例えばマーカーなど)を軽量かつハイパフォーマンスに構築してくれる」
といったところでしょうか。
フォルダ構成
まず、フォルダ構成は以下です。
.
└── src/
├── hiro.patt
├── index.html
└── Strawberry.gltf
-
hiro.patt は、AR.js のデフォルトマーカーです。
-
Strawberry.gltf は、「Free3D」というサイトから取得しました。
- 参考:https://free3d.com/ja/3d-models/
- ちなみに、glTF (GL Transmission Format) とはJSONによって3Dモデルやシーンを表現する一般的なフォーマットです。
実装
index.html の実装は以下です。
<!DOCTYPE html>
<html>
<head>
<title>AR Example2</title>
<!-- A-Frameを読み込む -->
<script src="https://aframe.io/releases/1.6.0/aframe.min.js"></script>
<!-- AR.js(A-Frame用)を読み込む -->
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
<meta name="apple-mobile-web-app-capable" content="yes" />
</head>
<body style="margin: 0; overflow: hidden">
<!-- シーンを作成 -->
<a-scene embedded arjs="sourceType: webcam;">
<a-assets>
<!-- 3Dモデルを読み込む -->
<a-asset-items id="Strawberry" src="/Strawberry.gltf"></a-asset-items>
</a-assets>
<!-- マーカー(今回はhiroマーカー)を検出して立方体を表示する -->
<!-- emitevents=true でマーカーの検出イベントを有効にする -->
<a-marker preset="hiro" emitevents="true">
<!-- 3Dモデルを呼び出す -->
<!-- gltfファイル(a-gltf-modelタグ)-->
<!-- <a-gltf-model scr="#Strawberry"></a-gltf-model> ←なぜか表示されない場合がある -->
<a-entity
position="0 0 0"
rotation="0 0 0"
scale="0.7 0.7 0.7"
gltf-model="#Strawberry"
>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
<script>
document
.querySelector("a-marker")
.addEventListener("markerFound", (event) => {
console.log("Marker Found", event);
});
document
.querySelector("a-marker")
.addEventListener("markerLost", (event) => {
console.log("Marker Lost", event);
});
</script>
</body>
</html>
先人たちの作ってみたサイトを見ても王道な形かなと思います。
以下、躓いたところです。
-
A-Frameの
<a-gltf-model />
というタグを使おうとしましたが、なぜか3Dオブジェクトが表示されないことがあったので、<a-entity />
を使い、gltf-model
という属性にIdを指定する形にしました。 -
このindex.htmlファイルをそのままブラウザで開くと以下のエラーが出ます。
Access to fetch at 'file:///{自分が配置したパス}/Strawberry.gltf' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrome-extension, chrome-untrusted, data, http, https, isolated-app.
このエラーメッセージは、CORS(Cross-Origin Resource Sharing)ポリシーに関連しています。具体的には、ブラウザがローカルファイル(file:///)からリソースを読み込むことを許可していないために発生しています。
CORSは、異なるオリジン(プロトコル+ドメイン+ポート)間でのリソースの共有を制御するためのセキュリティ機能です。ローカルファイルを直接ブラウザで開くと、オリジンがnullと見なされ、他のオリジンからのリソースへのアクセスがブロックされます。どこかのサーバーに配置すればいいのですが、今回はローカルで簡易的なサーバーを立てて、そのサーバーを通してファイルにアクセスすることにします。
自分のPCにはNode.js
が入っていたので、VSCodeのターミナルから以下を実行しました。npx http-server
その後、ブラウザで http://localhost:8000/ にアクセスすることで解消されました!
終わりに
上記を通して以下のように表示することができました。
(右側に開発者ツールのコンソールを表示しています)
ちなみに、<script/>
タグに書いていたイベントのおかげで、マーカーを検知できたかどうかを確認することができ、これが地味にありがたかったです!
動作確認の際、3Dオブジェクトが表示されないとき、「マーカーが検知できていないのか」「3Dオブジェクトが表示できていないのか」の区別をつけるためですね。
これから実装してみようという方はぜひこれも書いておきましょう。
WebARを使って、3Dオブジェクトだけでなく、画像や動画なども表示できるので使い方はたくさんありそうです。