お手軽360°パノラマ制作入門!
JSでパノラマビューワーを自作しよう

39
84
22

360°の全方向を自由に見渡せるパノラマコンテンツは、GoogleストリートビューのようなWebサービスによって身近なものになってきています。前回の記事「お手軽360°パノラマ制作入門! THETAで撮影しWeb公開に挑戦しよう」では、360°の静止画・動画が撮影できるカメラ「RICOH THETA S」で撮影したパノラマをYouTubeなどのWebサービスで手軽に公開する方法を紹介しました。

今回は、カスタマイズ性の高いWeb用の360°パノラマビューワーの実装方法を、初心者用と上級者用として2通り紹介します。初心者用のものはHTMLで3Dを作成できるライブラリ「A-Frame」を使い、上級者用としてはJavaScript製の3Dライブラリ「Three.js」を用います。

パノラマ静止画を表示する360°パノラマビューワー

次のデモは、本記事で解説するサンプルの完成形です。360°パノラマビューワーで、パソコンではマウスドラッグ、スマートフォンではジャイロセンサー(傾き)で視点を操作できます。手元の端末でお試しください。

本記事で紹介するデモのソースコードはGitHubに公開してます。ソースコードをダウンロードした上で記事を読み進めてください。それではこのサンプルの作り方を解説します。

360°パノラマビューワーの仕組み

360°パノラマビューワーの仕組みは意外と単純です。3D空間上に球体を配置し、パノラマ静止画をテクスチャーとして貼り付けます。その球体の中心にカメラを配置し、ぐるぐると視点を切り替えると360°の全方向を見渡せる360°パノラマビューワーの完成です。

▲RICOH THETA Sで撮影したパノラマ

A-FrameでHTMLをマークアップするように手軽に実装する方法

360°パノラマビューワーのような3Dコンテンツを実装する聞くと難しく感じる方もいると思いますが、MozillaのVRチームが開発した3Dライブラリ「A-Frame」を使うと、HTMLのマークアップのように手軽に実装できます。

▲A-Frameの公式ページ

A-Frameで作成したパノラマ静止画を表示する360°パノラマビューワーをお試しください。

続いて動画バージョンのデモもお試しください。スマートフォン・タブレットは未対応なので、パソコンで再生ください。

ここでは、JavaScriptにあまり触れたことのない方を対象に、A-Frameのダウンロード方法からパノラマ静止画・動画を表示できる360°パノラマビューワーの実装方法までを順を追って紹介します。手順通りに進めれば十数行のコードで実装できます。

※ A-Frameの詳しい使い方は記事「HTMLタグで本格VRコンテンツが作れる! Mozillaが開発した3Dライブラリ「A-Frame」がすごい」を参照ください。

1. ライブラリのダウンロード

A-FrameのGitHubページからライブラリをダウンロードします。GitHubページの右上にある[Clone or download]ボタンをクリックし、その中から[Download ZIP]をクリックします。すると、ライブラリのデータが入ったZIPファイルがダウンロードされるので、任意の場所に展開します。

2. HTMLからライブラリを読み込む

展開したaframe-masterフォルダー内のdistフォルダーにaframe-v0.4.0.min.jsというJavaScriptファイルがあるので、作業する任意の場所に格納します。そのJavaScriptファイルを、次のようにHTMLから読み込むだけで準備完了です。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <!-- A-FrameのJavaScriptファイルを読み込みます -->
  <script src="../common/js/aframe-v0.4.0.min.js"></script>
</head>
<body>
<!-- A-Frameのタグを記述します -->
</body>
</html>

3. シーンの作成

球体とカメラを配置する3D空間(シーン)を作成します。A-Frameでは、シーンにオブジェクトを追加してコンテンツを作っていきます。a-scene要素をbody要素内に記述すると簡単にシーンが作成できます。

<body>
  <!-- シーン -->
  <a-scene></a-scene>
</body>

4. パノラマ静止画の読み込み

A-Frameでパノラマ静止画などの外部ファイルを使用するときは、a-assets要素内にimg要素で指定します。読み込んだパノラマ静止画をテクスチャーとして参照するためにid属性を記述します。

<body>
  <!-- シーン -->
  <a-scene>
    <!-- アセット -->
    <a-assets>
      <img id="sky" src="../common/images/image.jpg">
    </a-assets>
  </a-scene>
</body>

5. 読み込んだパノラマ静止画を背景に指定する

読み込んだパノラマ静止画を背景として設定するには、a-sky要素を指定します。a-sky要素のsrc属性に、img要素のid属性を記述すると背景として表示されます。これでパノラマ静止画を表示する360°パノラマビューワーの完成です。

<body>
  <!-- シーン -->
  <a-scene>
    <!-- アセット -->
    <a-assets>
      <img id="sky" src="../common/images/image.jpg">
    </a-assets>
    <!-- 全天球背景 -->
    <a-sky src="#sky" rotation="0 -130 0"></a-sky>
  </a-scene>
</body>

360°パノラマビューワーの仕組みで「中心にカメラを配置する」と解説しましたが、A-Frameでは初期状態でカメラがシーンの中央に配置されているため、とくにカメラの設定は行いません。

発展:パノラマ動画を読み込む場合

パノラマ静止画の代わりにパノラマ動画を背景として表示するには、a-assets要素内にvideo要素を指定し、a-videosphere要素で参照するだけで簡単に実装できます。

<body>
  <!-- シーン -->
  <a-scene>
    <!-- アセット -->
    <a-assets>
      <!-- 動画をループ再生する -->
      <video id="video" src="../common/videos/video.mp4" loop="true"></video>
    </a-assets>
    <!-- 全天球背景 -->
    <a-videosphere src="#video" rotation="0 -130 0"></a-videosphere>
  </a-scene>
</body>

Three.jsで本格的に実装する方法

自由にカスタマイズしたり、凝ったインタラクションを加えたい場合は、JavaScript製の3Dライブラリとして有名なThree.jsで実装します。Three.jsを使えばA-Frameで実装するよりも設計の自由度が高いため、幅広い用途で利用できます。

Three.jsで作成したパノラマ静止画を表示する360°パノラマビューワーをお試しください。

続いて動画バージョンのデモもお試しください。スマートフォン・タブレットは未対応なので、パソコンで再生ください。

ここでは、JavaScriptの経験がある方を対象に、360°パノラマビューワーの実装に便利なモジュールの使い方から、パノラマ静止画・動画を表示できる360°パノラマビューワーの実装方法までを順を追って紹介します。

1. ライブラリのダウンロード

Three.js公式サイトにある[download]ボタンをクリックし、ライブラリのデータが入ったZIPファイルをダウンロードします。ZIPファイルを展開したthree.js-masterフォルダーから次の3つのJavaScriptファイルを任意の場所に格納します。

  • build/three.min.js
    Three.jsの本体ライブラリ
  • examples/js/controls/DeviceOrientationControls.js
    スマートフォンのジャイロセンサーの傾きをコンテンツに反映させるモジュール
  • examples/js/controls/OrbitControls.js
    パソコンで確認時にマウスドラッグで視点を切り替えられるようにするモジュール

2. HTMLからライブラリを読み込む

先ほどダウンロードしたライブラリと、メインの処理を実装するJavaScriptファイルをHTMLから読み込みます。

<!-- three.jsの読み込み -->
<script src="../common/js/three.min.js"></script>
<!-- DeviceOrientationControls.jsの読み込み -->
<script src="../common/js/DeviceOrientationControls.js"></script>
<!-- OrbitControls.jsの読み込み -->
<script src="../common/js/OrbitControls.js"></script>
<!-- main.jsの読み込み -->
<script src="js/main.js" ></script>

3. シーンの作成

球体とカメラを配置するシーンを作成します。

// シーンの作成
scene = new THREE.Scene();

4. カメラの作成

カメラを作成し、さきほどのシーンへXYZ座標すべてが0になるように配置します。

// カメラの作成
camera = new THREE.PerspectiveCamera(
  75,
  width / height,
  1,
  1000
);
camera.position.set(0, 0, 0);
scene.add(camera);

5. 球体を作成してパノラマ静止画をテクスチャーとして設定

球体を作成してパノラマ静止画をテクスチャーとして設定します。設定できたらシーンへ配置します。

// 球体の形状を作成
var geometry = new THREE.SphereGeometry(5, 60, 40);
geometry.scale(-1, 1, 1);

// マテリアルの作成
var material = new THREE.MeshBasicMaterial({
  // 画像をテクスチャーとして読み込み
  map: THREE.ImageUtils.loadTexture(
    "../common/images/image.jpg"
  )
});

// 球体(形状)にマテリアル(質感)を貼り付けて物体を作成
sphere = new THREE.Mesh(geometry, material);

// シーンに追加
scene.add(sphere);

6. パソコンで閲覧時の視点操作する処理を実装

パソコンで閲覧時は、マウスドラッグで視点を操作します。実装にはダウンロードしたOrbitControls.jsを使います。パソコンでの操作を想定していない場合は、省いてしまっても問題ありません。

// パソコン閲覧時マウスドラッグで視点操作する
function setOrbitControls() {
  controls = new THREE.OrbitControls(camera, element);
  controls.target.set(
    camera.position.x + 0.15,
    camera.position.y,
    camera.position.z
  );
  // 視点操作のイージングをONにする
  controls.enableDamping = true;
  // 視点操作のイージングの値
  controls.dampingFactor = 0.2;
  // 視点変更の速さ
  controls.rotateSpeed = 0.1;
  // ズーム禁止
  controls.noZoom = true;
  // パン操作禁止
  controls.noPan = true;
}

7. スマートフォンで閲覧時の視点操作する処理を実装

スマートフォンで閲覧時は、端末に搭載されているジャイロセンサー(傾き)で視点を操作します。実装にはダウンロードしたDeviceOrientationControls.jsを使います。

// スマートフォンの場合はジャイロセンサーでの操作へ変更
window.addEventListener(
  "deviceorientation",
  setOrientationControls,
  true
);

// ジャイロセンサーで視点操作する
function setOrientationControls(e) {
  //スマートフォン以外で処理させない
  if (!e.alpha) {
    return;
  }
  controls = new THREE.DeviceOrientationControls(
    camera,
    true
  );
  controls.connect();
  controls.update();
  window.removeEventListener(
    "deviceorientation",
    setOrientationControls,
    true
  );
}

8. 視点操作処理をレンダラーに登録

最後に3Dの描画をレンダリングするレンダラーに、視点操作処理を登録すると視点操作が可能になります。これでパノラマ静止画を表示する360°パノラマビューワーの完成です。

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
  controls.update();
}

発展パノラマ動画をテクスチャーとして設定する場合

「5. 球体を作成してパノラマ静止画をテクスチャーとして設定」のコードを次のように変更すると、パノラマ動画をテクスチャーとして設定できます。

// 球体の形状を作成
var geometry = new THREE.SphereGeometry(5, 60, 40);
geometry.scale(-1, 1, 1);

// 動画の読み込み
var video = document.createElement("video");
video.src = "../common/videos/video.mp4";
video.load();
video.play();
video.loop = true;

// テクスチャーにvideoを設定
texture = new THREE.VideoTexture(video);
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;

// マテリアルの作成
var material = new THREE.MeshBasicMaterial({
  // 画像をテクスチャーとして読み込み
  map: texture
});

// 球体(形状)にマテリアル(質感)を貼り付けて物体を作成
sphere = new THREE.Mesh(geometry, material);

// シーンに追加
scene.add(sphere);

最後に

今回は、「A-Frame」と「Three.js」を使った360°パノラマビューワーの基本的な実装方法を紹介しました。こちらをベースに、3Dモデルを動かしたり、インタラクションによってパノラマを切り替えたりとカスタマイズを加えることで、オリジナルの360°パノラマコンテンツが作成できます。

また、パノラマはVR(Virtual Reality)と相性がよく、作成した360°パノラマビューワーに一手間加えるだけで、VRコンテンツも作成できます。ICS MEDIAでは、1,000円ほどで購入できるダンボール製VRヘッドセット「Google Cardboard」を使って、手軽にVRコンテンツを作成する記事を公開していますので、ぜひ挑戦してみてください!

▲Google Cardboard