aframeを追加する

This commit is contained in:
ry.yamafuji 2025-03-27 02:22:39 +09:00
parent b76affe2f7
commit 184eba34e1
5 changed files with 338 additions and 48 deletions

246
docs/ar-xr.md Normal file
View File

@ -0,0 +1,246 @@
# [開発]AR/XRの利用ガイドライン
## AR/XEについて定義
空間の概念
* 空間の中に仮想オブジェクトが配置
* ユーザーが空間内を自由に移動または視点操作できる
## 利用例と対応技術
1. **GPS、カメラなどのセンサ情報と連動**
- 仮想オブジェクトを現実に重ねる
- 例ポケモンGOのように位置情報と連動して表示される仮想キャラクター。
2. **ユーザーとのインタラクション**
- タップ、ジェスチャー、視線、音声などを通じた操作が可能。
- 例:展覧会アプリでアート作品に近づくと詳細情報が表示される。
3. **空間認識 / 環境マッピング**
- ARKitやARCoreなどで現実の床・壁・物体を認識して、仮想オブジェクトを自然に配置。
- 例家具ARアプリが部屋の床にテーブルを正確に置く
4. **空間を活かしたUX設計**
- 単なるUI配置ではなく、「空間に存在する意味」を考慮した設計。
- 例不動産カタログがモデルルーム内を歩き回るUXで部屋の広さや窓の位置を体験できる。
| 利用例 | 空間性 | 使用技術 | 特記事項 |
| ---------------- | -------- | ----------------- | -------------------------------- |
| 歩行型Web展覧会 | あり | WebXR + A-Frame等 | 空間移動・近接操作あり |
| ポケモンGO | あり | ARKit/ARCore | GPS連動・カメラ合成あり |
| 商品カタログ(3D) | 条件付き | WebAR / Unity等 | 操作・空間性の有無で評価分かれる |
### 類似技術(ARではない例)
| 例 | 理由 |
| -------------------------------------------------- | -------------------------------------------------------- |
| カメラ映像の上にキャラクターを表示するだけのアプリ | 空間と連動していないため「ただの合成」 |
| 背景がカメラ映像の3Dゲーム | 現実との関係がないのでARではない |
| Instagramのエフェクトの一部目に星を重ねるなど | 空間ARというよりはフェイストラッキング or エフェクト処理 |
## スタック
### フロントエンド(AR体験を提供する側)
| デバイス | 技術・ライブラリ |
| -------- | -------------------- |
| iOS | ARKit(Apple純正) |
| Android | ARCoreGoogle純正 |
**Web向けAR**
| ライブラリ | 特徴 | 難易度 | 拡張性 | 主な用途 |
| ---------- | --------------------------------------------- | ------ | -------- | -------------------- |
| A-Frame | HTMLベースで簡単に3Dコンテンツ。初心者向き | 低 | 中 | プロトタイピングなど |
| Three.js | 高機能3Dライブラリ。低レベル制御が可能 | 中〜高 | 高 | 複雑な3D表現 |
| AR.js | WebAR用ライブラリ。Three.js/A-Frameと併用可能 | 中 | 中 | マーカーAR、GPS AR |
| 8thWall | 高精度WebARプラットフォーム有料 | 低 | 高 | 実用ARアプリ |
| WebXR API | ブラウザ標準のAR/VR API | 高 | 非常に高 | 本格的なAR/VRアプリ |
* iOSの制約ポイント(2025年)
* カメラアクセス Safariのみが原則的に対応(PWAやChromeは制限あり)
* WebXR API:サポートされていない2025年現在
* WebRTC/MediaDevices getUserMediaはOK。(AR.jsの一部機能が動作不安定)
その他の仕様する技術について
| Flutter | |
| ------- | --------------------------------------------- |
| Unity | AR FoundationARKit + ARCoreの抽象化 |
| Flutter | ar_flutter_plugin(公式ARSDKのFlutterラッパー) |
| | |
### バックエンド
必要な場合のみ実装
*クラウド処理
* 画像認識AI
* 地図情報
* マルチユーザー同期
WebSocketやMQTTでリアルタイム連携する
### A-Frameエーフレーム
Webブラウザ上で3DコンテンツやVR/AR体験を作れるHTMLベースのフレームワーク
JavaScriptが得意でなくても、**HTMLタグ感覚で簡単に使える**
* 公式チュートリアル: https://aframe.io/docs/master/introduction/
#### 使用方法について
A-FrameはCDNで使えます。
HTMLの<head>に以下を追加する
```html
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
```
## Three.js + AR.js
Three.jsは WebGLを抽象化し、高機能な3D描画をJavaScriptで行える軽量ライブラリです。
ARやVRだけでなくゲームやインタラクティブなグラフィック表現にも使われます
- 公式: https://threejs.org/
- GitHub: https://github.com/mrdoob/three.js/
AR.jsは、Three.jsベースで動作する**WebARライブラリ**。
マーカー認識や位置情報を使ったAR体験を提供。
- 公式: https://ar-js-org.github.io/AR.js-Docs/
#### 特徴
**Three.js**
- カスタマイズ性が高く、細かい3D制御が可能
- WebAR/VR対応にも拡張しやすい
- A-Frameに比べて**記述量は多め**だが、**柔軟性が高い**
**AR.js**
- モバイルブラウザでも軽快に動作60fpsも実現可能
- **マーカーベースAR**Hiroマーカーなどと**位置情報ベースAR**の両方に対応
- **A-Frameとも連携可能**
---
### 使用方法についてThree.js + AR.js
Three.jsのシーンを作成し、AR.jsと連携してカメラ映像と重ねて表示します。
主に以下のステップで構成されます:
1. カメラの取得(`ARjs.Context`
2. Three.jsのシーン、カメラ、レンダラーの準備
3. マーカー検出(`ARjs.MarkerControls`を使って3Dモデル表示
#### サンプルコードマーカーベースAR
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AR.js マーカーベース サンプル</title>
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/AR-js-org/AR.js@3.3.2/aframe/build/aframe-ar.min.js"></script>
<style>
body { margin: 0; overflow: hidden; }
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0,0,0,0.5);
padding: 5px 10px;
font-family: sans-serif;
z-index: 999;
}
</style>
</head>
<body>
<div id="info">「Hiroマーカー」をカメラにかざしてください</div>
<a-scene embedded arjs="sourceType: webcam; debugUIEnabled: false;">
<!-- マーカーが認識されたときに表示される青い箱 -->
<a-marker preset="hiro">
<a-box position="0 0.5 0" material="color: blue;" shadow></a-box>
<a-text value="Hello AR!" position="-0.5 1 0" color="white"></a-text>
</a-marker>
<!-- カメラ -->
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
```
* Webカメラ対応のPCまたはスマホのブラウザ
*
## A-Frameの基本
### A-Frameの導入
A-FrameはCDNで使えます。HTMLの`<head>`に以下を追加するだけ:
```html
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
```
| タグ | 説明 |
| -------------- | ------------------------------------------ |
| `<a-scene>` | A-Frameの世界のルート必須 |
| `<a-box>` | 箱を表示(位置、回転、色、サイズを指定可) |
| `<a-sphere>` | 球体 |
| `<a-cylinder>` | 円柱 |
| `<a-plane>` | 平面。地面に使われることが多い |
| `<a-text>` | テキスト表示 |
| `<a-camera>` | 視点を定義。省略すると自動的に追加される |
| `<a-light>` | 光源。明るさや影の描画に必要 |
## サンプルコード
### A-Frameで作る歩行型Webページ
```html
<!DOCTYPE html>
<html>
<head>
<title>歩行型Webページ</title>
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
</head>
<body>
<a-scene>
<!-- 地面 -->
<a-plane position="0 0 0" rotation="-90 0 0" width="50" height="50" color="#7BC8A4"></a-plane>
<!-- カメラとコントロールWASDキーで歩行可能 -->
<a-entity camera wasd-controls look-controls position="0 1.6 5"></a-entity>
<!-- 建物風のオブジェクト -->
<a-box position="0 0.5 -5" depth="5" height="1" width="5" color="#4CC3D9"></a-box>
<a-box position="10 0.5 -5" depth="5" height="1" width="5" color="#FFC65D"></a-box>
<a-sphere position="-10 1 -5" radius="1" color="#EF2D5E"></a-sphere>
</a-scene>
</body>
</html>
```
#### 特徴
- **マウス視点移動**:マウスで見回せます。
- **WASDキーで歩行**:前後左右に移動できます。
- **HTMLだけで構成**JavaScriptなしでA-Frameがほとんど自動処理。
#### 移動の制御
- `wasd-controls`: W/A/S/Dキーで歩けるようにする
- `look-controls`: マウスで視点を変える
#### 応用例
* [ホバーイベント:](../src\front\ar\afreame\aframe-hover.html)

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ホバーで説明表示</title>
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
</head>
<body>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: .hoverable">
<!-- 地面 -->
<a-plane position="0 0 0" rotation="-90 0 0" width="50" height="50" color="#7BC8A4"></a-plane>
<!-- カメラ -->
<a-entity wasd-controls camera look-controls position="0 1.6 5"></a-entity>
<!-- 展示物 -->
<a-box id="exhibit" class="hoverable" position="0 0.5 -5" color="#4CC3D9" depth="1" height="1" width="1"></a-box>
<!-- 説明テキスト(最初は非表示) -->
<a-text id="tooltip" value="これは展示物です" visible="false"
position="0 1.5 -5" color="#000" align="center" width="4">
</a-text>
<!-- イベントスクリプト -->
<script>
AFRAME.registerComponent('show-tooltip', {
init: function () {
const tooltip = document.querySelector('#tooltip');
this.el.addEventListener('mouseenter', () => {
tooltip.setAttribute('visible', 'true');
});
this.el.addEventListener('mouseleave', () => {
tooltip.setAttribute('visible', 'false');
});
}
});
document.addEventListener('DOMContentLoaded', () => {
const exhibit = document.querySelector('#exhibit');
exhibit.setAttribute('show-tooltip', '');
});
</script>
</a-scene>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AR.js マーカーベース サンプル</title>
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/AR-js-org/AR.js@3.3.2/aframe/build/aframe-ar.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
#info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0, 0, 0, 0.5);
padding: 5px 10px;
font-family: sans-serif;
z-index: 999;
}
</style>
</head>
<body>
<div id="info">「Hiroマーカー」をカメラにかざしてください</div>
<a-scene embedded arjs="sourceType: webcam; debugUIEnabled: false;">
<!-- マーカーが認識されたときに表示される青い箱 -->
<a-marker preset="hiro">
<a-box position="0 0.5 0" material="color: blue;" shadow></a-box>
<a-text value="Hello AR!" position="-0.5 1 0" color="white"></a-text>
</a-marker>
<!-- カメラ -->
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
F

View File

@ -1,48 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ホバーで説明表示</title>
<script src="https://aframe.io/releases/1.4.2/aframe.min.js"></script>
</head>
<body>
<a-scene>
<!-- 地面 -->
<a-plane position="0 0 0" rotation="-90 0 0" width="50" height="50" color="#7BC8A4"></a-plane>
<!-- カメラと移動 -->
<a-entity camera wasd-controls look-controls position="0 1.6 5"></a-entity>
<!-- 展示物 -->
<a-box id="exhibit" position="0 0.5 -5" color="#4CC3D9" depth="1" height="1" width="1"></a-box>
<!-- 説明テキスト(最初は非表示) -->
<a-text id="tooltip" value="これは展示物です" visible="false" position="0 1.5 -5" color="#000" align="center" width="4">
</a-text>
<!-- イベントスクリプト -->
<script>
AFRAME.registerComponent('show-tooltip', {
init: function () {
const tooltip = document.querySelector('#tooltip');
this.el.addEventListener('mouseenter', () => {
tooltip.setAttribute('visible', 'true');
});
this.el.addEventListener('mouseleave', () => {
tooltip.setAttribute('visible', 'false');
});
}
});
// 展示物にイベントコンポーネントを適用
document.addEventListener('DOMContentLoaded', () => {
const exhibit = document.querySelector('#exhibit');
exhibit.setAttribute('show-tooltip', '');
});
</script>
</a-scene>
</body>
</html>