立方パノラマ表示 WebGL Panorama 修正版

Ruby+GLUT 版に相当する WebGL パノラマ表示スクリプトを既に誰かが作ってないかと探してみたら、 「WebGL Panorama by ulfbiallas」が見つかりました。 ただし、 これの立方体表面画像との対応は WebGL のキューブ・マップに合わせてあり、 そのままでは QuickTime Cubic VR 用画像との対応が悪いため、 テクスチャ・マッピングを修正しました。 さらに、 修正版を使った立方パノラマを表示するページを試作してみました。

https://tociyuki.sakura.ne.jp/album/cubicvr02/DSCN3019.html

うまく動いているようなので、 本館の「パノラマ 2006年版」を WebGL で表示できるように変更しました。

https://tociyuki.sakura.ne.jp/album/cubicvr06/index.html

正面画像を xp とし、 右画像を zp、 背面画像を xn、 左画像を zn、 上画像を yp、 下画像を yn へそれぞれ指定します。

<script src="http://code.jquery.com/jquery-3.2.0.min.js"></script>
<script src="../jquery-webglpanorama-p1.js"></script>
<script>
$(function() {
  $('#pano').panorama({
    'xp': 'DSCN3019/0.jpg',
    'zp': 'DSCN3019/1.jpg',
    'xn': 'DSCN3019/2.jpg',
    'zn': 'DSCN3019/3.jpg',
    'yp': 'DSCN3019/4.jpg',
    'yn': 'DSCN3019/5.jpg'
  });
});
</script>

<canvas id="pano" width="480" height="320"></canvas>

オリジナルからの修正は 3 ヶ所です。

1. 表示開始時に正面画像を表示するように、 phi をゼロに変更しました。

    $.fn.panorama = function (options) {
        this.each(function () {
            //略
            var data = {
                //略
                'phi' : 0,
                //phi : -90,
                //略
            };
            //略
        });
        return this;
    }

2. 立方体頂点を Ruby+GLUT のものへ変更しました。 3次元上でのテクスチャ貼り付け三角形頂点列も、 変更した立方体頂点を使うように変更しました。

    function createModel(data) {
        var vertices = new Float32Array([
        +1.0, +1.0, -1.0, 0.0, 0.0,
        +1.0, -1.0, -1.0, 0.0, 1.0,
        +1.0, -1.0, +1.0, 1.0, 1.0,
        +1.0, +1.0, +1.0, 1.0, 0.0,

        +1.0, +1.0, +1.0, 0.0, 0.0,
        +1.0, -1.0, +1.0, 0.0, 1.0,
        -1.0, -1.0, +1.0, 1.0, 1.0,
        -1.0, +1.0, +1.0, 1.0, 0.0,

        -1.0, +1.0, +1.0, 0.0, 0.0,
        -1.0, -1.0, +1.0, 0.0, 1.0,
        -1.0, -1.0, -1.0, 1.0, 1.0,
        -1.0, +1.0, -1.0, 1.0, 0.0,

        -1.0, +1.0, -1.0, 0.0, 0.0,
        -1.0, -1.0, -1.0, 0.0, 1.0,
        +1.0, -1.0, -1.0, 1.0, 1.0,
        +1.0, +1.0, -1.0, 1.0, 0.0,

        -1.0, +1.0, -1.0, 0.0, 0.0,
        +1.0, +1.0, -1.0, 0.0, 1.0,
        +1.0, +1.0, +1.0, 1.0, 1.0,
        -1.0, +1.0, +1.0, 1.0, 0.0,

        +1.0, -1.0, -1.0, 0.0, 0.0,
        -1.0, -1.0, -1.0, 0.0, 1.0,
        -1.0, -1.0, +1.0, 1.0, 1.0,
        +1.0, -1.0, +1.0, 1.0, 0.0 
        ]);

        var indices = new Uint16Array([
         0,  1,  3,
         1,  2,  3,

         4,  5,  7,
         5,  6,  7,

         8,  9, 11,
         9, 10, 11,

        12, 13, 15,
        13, 14, 15,

        16, 17, 19,
        17, 18, 19,

        20, 21, 23,
        21, 22, 23
        ]);
        //略
    }

3. テクスチャ描画を上の座標へ合わせて変更しました。

    function draw(data) {
        //略
        gl.bindTexture(gl.TEXTURE_2D, data.texture_xp);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
        gl.bindTexture(gl.TEXTURE_2D, data.texture_zp);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 6*2);
        gl.bindTexture(gl.TEXTURE_2D, data.texture_xn);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 12*2);
        gl.bindTexture(gl.TEXTURE_2D, data.texture_zn);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 18*2);
        gl.bindTexture(gl.TEXTURE_2D, data.texture_yp);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 24*2);
        gl.bindTexture(gl.TEXTURE_2D, data.texture_yn);
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 30*2);
        data.animationId = requestAnimationFrame(function() {return draw(data);});
    }