THETA S で全天球映像を配信するまで(2) UVマッピングを作ってみました
- WebRTC
- 2016/01/22
こんにちは、インフォコム技術企画室のがねこです。
来る2016年2月16日、17日に行われる、WebRTC Conference Japan 2016でRICOH THETA S を使ったリアルタイム全天球配信のデモを展示する予定です。今回はTHETA S から取得できるライブ映像を、WebGLの球面上に貼り付ける準備をやってみます。
前回は映像の形式について調べました。全天球映像として表示するには、これをWebGLの3D空間内の、球面に貼り付けなくてはなりません。2つの円のそれぞれを、半球に貼り付けます。(前回記載した通り、実際に欲しい領域は楕円になります)
貼り付ける方法はUVマッピングと呼ばれる方法と、シェーダーと呼ばれる方法があるようです。今回はUVマッピングと呼ばれる方法を利用しています。
おおざっぱに言うと、UVマッピングでは次の図のように平面の座標と立体上の座標を対応させるようです。今回は楕円形を半球に対応させていきます。
このUVマッピングを実現するまでは、遠い道のりでした。
凹みさんによるUnityでのマッピング
VRやスマートホームなどの実験を積極的に公開している 凹みさんが、Unityを使ってTHETA S の映像を3D空間にマッピングする方法を公開していました。
発売前に RICOH THETA S のライブビューを Unity でリアルタイムに全天球で見るやつ作ってみた
このマッピング用のデータを使う許可をtwitter上でお願いしたところ、快く了承いただいたので利用させていただきました。
Blenderでの読み込み、微調整
3DモデリングのBlenderというツールがあります。これを用いてUnityのマッピングデータを読み込み、調整しました。
(1) Unityからモデルの読み込み
Unityのプロジェクトから、.fbxファイルを読み込みます。
(2) 180度を越える重なり部分を除去
凹さんの元の方法では水平方向の180度を越える部分は半透明にして重なり合わせているようです。これを今回はぶっつりと切り落とします。
その結果、下図のように半球と元の映像の楕円部分が対応することになります。
(3) 2つの半球を調整
ここからは微妙なマウスさばきで半球の映像の位置関係を調整します。チームメンバーの一人にやってもらいましたが、職人芸の世界です。
反対側も同じく調整します。
Three.js(WebGLライブラリ)用にエクスポート
作ったマッピングを、WebGLライブラリであるThree.js用にエクスポートします。そのためにはThree.jsに含まれるアドオンが必要です。こちらの記事を参考にしながら、Three.jsのio_mesh_threejs ディレクトリを、Blender アドオン用ディレクトリの配下にコピーしました。
反対側もエクスポートします。
Three.jsでの読み込み
ようやくWebの世界まで来ました。WebGLのライブラリであるThree.jsで、先ほどエクスポートしたjsonファイルを読み込みます。
var loader = new THREE.JSONLoader(true); // init the loader util
loader.load('uv/half_sphere_1.json', function(geometry1, materials1) {
// create a new material
var material1 = new THREE.MeshPhongMaterial({
map: videoTexture, // specify and load the texture
color: 0xffffff,
specular: 0xcccccc,
shininess: 50,
ambient: 0xffffff,
overdraw: true
});
// create a mesh with models geometry and material
var mesh1 = new THREE.Mesh(
geometry1,
material1
);
// mesh1.rotation.y = -Math.PI/5;
mesh1.scale.set(0.1, 0.1, 0.1);
mesh1.position.set(0, 0, 0).normalize();
scene.add(mesh1);
});
loader.load('uv/half_sphere_2.json', function(geometry2, materials2) {
// create a new material
var material2 = new THREE.MeshPhongMaterial({
map: videoTexture, // specify and load the texture
color: 0xffffff,
specular: 0xcccccc,
shininess: 50,
ambient: 0xffffff,
overdraw: true
});
// create a mesh with models geometry and material
var mesh2 = new THREE.Mesh(
geometry2,
material2
);
// mesh2.rotation.y = -Math.PI/5;
mesh2.scale.set(0.1, 0.1, 0.1);
mesh2.position.set(0, 0, 0).normalize();
scene.add(mesh2);
});
ライブラリの公開
今回調べた内容を私たちのデモから切り離し、自由にお使いいただける形でgithubに公開しています。ご興味のある方は、ぜひお試しください。
- GitHub THETA_GL
- GitHub pages THETA_GL
sample page
参考
他にもTHETA Sの映像をWebGLで表示する方法が公開されています。一部ではとてもホットな話題になっています。
UVマッピング方式
THETA S のUSBライブストリーミングをブラウザで球面マップする
THETAのDualfisheye動画をThree.jsで表示してみた
シェーダー方式
https://github.com/gtk2k/gtk2k.github.io/tree/master/aframe_theta_s_live_preview