360度写真をThree.jsでパノラマ表示!自由な視点回転でリアルなバーチャル空間を体験
Three.jsを使って360度画像を球体にマッピングし、自由な視点回転が可能なパノラマ表示の実装例です。
OrbitControlsを使ってマウス操作で視点を回転させることができ、WebGLベースで軽量かつシンプルに構築できます。
スマホで撮影した全天球画像をWeb上で再現したい場合や、バーチャル空間の体験コンテンツとしても活用できます。
球体に360度パノラマ写真をテクスチャとして貼り、この球体の裏面を表示するようにマテリアル設定します。
カメラをこの球体の中心に配置してオービット コントロール(OrbitControls)でドラッグによる回転のみ許可すれば完成です。
Androidで撮影した360度写真を球体にテクスチャマッピングしています。

マウス左ドラッグで視点回転します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="content-language" content="ja">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0,user-scalable=yes">
<script src="./three_r145/three.min.js"></script>
<script src="./three_r145/OrbitControls.js"></script>
<script>
var scene,camera;
var main = function () {
//■シーンを作成
scene = new THREE.Scene();
//描画先canvasを取得
let can=document.getElementById('can');
//canvasの高さ,幅を取得
let w = parseInt(can.style.width);
let h = parseInt(can.style.height);
//■カメラを作って設定
//THREE.PerspectiveCamera( 画角(度), アスペクト比, カメラに写る最短距離, カメラに写る最長距離 );
camera = new THREE.PerspectiveCamera( 30, w/h, 0.1, 10000 );
camera.position.set( 0, 0, 1 );//カメラの位置を設定
scene.add( camera );
//■レンダラーをDOM(canvas)上に設置する
renderer = new THREE.WebGLRenderer({canvas:can , antialias: true});//アンチエイリアスをtureにする
renderer.setSize( w, h );
renderer.setClearColor(0x444444, 1);
//■テクスチャマッピング用画像のロードと設定
//球体に貼り付けるテクスチャ画像のロード
let Texture360=new THREE.TextureLoader().load('./three_r145/img/360.jpg');
Texture360.wrapS=THREE.RepeatWrapping;
Texture360.wrapT=THREE.RepeatWrapping;
//テクスチャの繰り返し回数を指定する
Texture360.repeat.set(1,1);
//球体用の基本マテリアルを作成する
let SphereMaterial=new THREE.MeshBasicMaterial({
color:0xFFFFFF,
side:THREE.BackSide,//裏面を表示する設定
map: Texture360
});
//球体ジオメトリの作成(半径、横分割数,高さ方向分割数)
let SphereGeometry=new THREE.SphereGeometry(1,32,24);
//球体のメッシュの作成
let SphereMesh=new THREE.Mesh(SphereGeometry,SphereMaterial);
scene.add(SphereMesh);
//マウスの左右ドラッグ+中ボタンの上下ホイールで動かす
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0,0,0);
controls.enablePan=false; //パンできなくする
controls.enableZoom=false;//ズームできなくする
controls.update();
renderLoop();
};
function renderLoop () {
requestAnimationFrame( renderLoop );
renderer.render( scene, camera );
}
window.addEventListener( 'DOMContentLoaded', main, false );
</script>
</head>
<body>
<canvas id="can" style="width:300px; height:180px;margin:0;padding:0;cursor:grab;"></canvas>
</body>
</html>
