リクルート住まいカンパニー Tech Blog

ITのちからで暮らしをよくしたい、エンジニア・デザイナーが発信するTech情報メディア

three.jsを利用したVR体験の実現 ① 全天球を表示してみる

f:id:recruit-sumai:20170309105724j:plain

こんにちは、スマートデバイス戦略開発グループの katayama です。

住まいカンパニーではSUUMOスコープ (SUUMOが提供するCardboardによるバーチャル物件内観のこと)を利用したVR (バーチャルリアリティ) 体験の提供を行っています。

SUUMOでは、アプリ / Webブラウザ のどちらからでも閲覧できるように、WebGLを利用して開発をしており、今回はこれを事例に、three.js を利用したVR体験の実装方法 (まずは全天球を表示してみるところまで) についてお話します。

SUUMOスコープとは

SUUMOスコープを使うと、VR (バーチャルリアリティ) 体験によって、マンションのモデルルーム等を家にいながらでも内見できるようになります。(※ 2016/02/23 (火) に第2弾をリリース) f:id:recruit-sumai:20170322182259j:plain

360° VR体験の仕組み

まずは、360°の画像をグリグリ回す仕組みを説明します。

① 球体のオブジェクト(geometoryと呼びます)を作り、その中心にカメラを配置 ② RICOH THETA などで、撮ったパノラマ画像をテクスチャとして球体に貼り付ける

③ デバイスの傾きなどから、カメラの方向を求める f:id:recruit-sumai:20170322182345p:plain こうすることで、球体の内側から画像を見ているような形で、360°のVR体験を実現することができます。

 

Three.js で全天球を表示してみる

それでは、さっそく球体のオブジェクトを作り、360°画像を貼り付けてみましょう! WebGLを簡単に扱うために、Three.js というライブラリを使って作ってみます。

①まずは、htmlにThree.js をインポート

vrcanvas の箇所に、<canvas>要素で描画することにします、

[index.html]
<!DOCTYPE html>
<html lang="jp">
<head>
   <title>" VR contents</title>
   <meta charset="utf-8">
    <meta id="viewport" name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body style="background:#000;">

    <script src="js/three.min.js"></script>
    <script src="js/main.js"></script>
</body>
</html>

② シーンの作成とカメラの配置

[js/main.js]

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

// カメラの作成
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

// レンダラーの作成
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );

// body にcanvas要素として描画エリアを追加
document.body.appendChild( renderer.domElement );
[/js]

<h3>③ 球体オブジェクトの作成と、360°画像のテクスチャ貼り付け</h3>
[js/main.js]

// 球体の形状を作成
var geometry = new THREE.SphereGeometry(1, 100, 100);

// 画像をテクスチャとして読み込み
var texture = new THREE.ImageUtils.loadTexture(&quot;photo.jpg&quot;);
texture.minFilter = THREE.LinearFilter;
texture.flipY = false;

// テクスチャを使い、マテリアル(質感)を作成
var material = new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide,
    color: 0xFFFFFF, specular: 0xcccccc, shininess:50, ambient: 0xffffff,
    map:texture
});

// 球体(形状)にマテリアル(質感)を貼り付けて物体を作成
var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x += Math.PI; // 球体を回転させ、方向を調整

// シーンに物体を配置
scene.add( mesh );

④ 描画を行う

最後に、scene と camera を指定してレンダリングする。 併せて、球体が自動で回転する処理を加えてみます

[js/main.js]
var render = function () {
 requestAnimationFrame( render );
 mesh.rotation.y += 0.003;
 renderer.render(scene, camera);
};
  window.requestAnimationFrame() メソッドは、ブラウザに描画させたいアニメーションを指定し、次の再描画の前に、アニメーションを更新する指定した関数を呼び出すように要求します。このメソッドは再描画する前に呼び出されるコールバックメソッドを引数にひとつとります。 https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame  

これで、以下のように360°画像を見ることができるようになりました! 歪みなく綺麗に見えていますね。

 

まとめると、以下の様なソースコードとなります。

[js/main.js]

// シーンの作成
var scene = new THREE.Scene();
// カメラの作成
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
// レンダラーの作成
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement ); // body にcanvas要素として描画エリアを追加

// 球体の形状を作成
var geometry = new THREE.SphereGeometry(1, 100, 100);

// 画像をテクスチャとして読み込み
var texture = new THREE.ImageUtils.loadTexture(&quot;photo.jpg&quot;);
texture.minFilter = THREE.LinearFilter;
texture.flipY = false;

// テクスチャを使い、マテリアル(質感)を作成
var material = new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide,
    color: 0xFFFFFF, specular: 0xcccccc, shininess:50, ambient: 0xffffff,
    map:texture
});

// 球体(形状)にマテリアル(質感)を貼り付けて物体を作成
var mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x += Math.PI; // 球体を回転させ、方向を調整

scene.add( mesh );

var render = function () {
    requestAnimationFrame( render );
    mesh.rotation.y += 0.003;
    renderer.render(scene, camera);
};

render();

 

次回は、デバイスの傾きに応じてカメラを回転させ、部屋全体を見れるようにしていき、 さらに2眼モード対応をしていきます。

→ three.jsを利用したVR体験の実現 ② カメラを回転とCardboard対応