基於WebGL的球體紋理貼圖實現全景展示

1 繪製球體

1.1 將球面映射到二維平面

三維球面座標與二維座標系之間的映射關係如下:
映射關係
歸一化表示爲:
歸一化

1.2 離散化

將座標系沿兩軸劃分多份,橫軸每份寬度爲δu,縱軸每份寬度爲δv,下圖便可以確定四個離散點的座標
離散化

1.3 計算球面座標代碼實現

/**
 * 計算球面座標
 * @param {number} uPieces u軸分割條數
 * @param {number} vPieces v軸分割條數
 */
let getPointArray = function (uPieces, vPieces) {
    /**
     * 計算 uv 座標系下的點對應的 webgl 座標系下的點
     * @param {number} u 橫軸座標
     * @param {number} v 縱軸座標
     */
    let getPoint = function (u, v) {
        let φ = u * 2 * Math.PI;
        let θ = v * Math.PI;
        let r = 1;
        let x = r * Math.sin(θ) * Math.sin(φ);
        let y = r * Math.cos(θ);
        let z = r * Math.sin(θ) * Math.cos(φ);
        return [x, y, z, u, v];
    }

    let δu = 1 / uPieces;
    let δv = 1 / vPieces;
    let result = [];
    for (let i = 0; i < vPieces; i++) {
        for (let j = 0; j < uPieces; j++) {
            // 一次構造4個點,兩個三角形
            let p1 = getPoint(j * δu, i * δv);
            let p2 = getPoint((j + 1) * δu, i * δv);
            let p3 = getPoint((j + 1) * δu, (i + 1) * δv);
            let p4 = getPoint(j * δu, (i + 1) * δv);
            // 將兩個三角形座標放入數組
            result.push(...p1, ...p4, ...p3, ...p1, ...p3, ...p2);
        }
    }
    return result;
}

1.4 球面效果

點的效果:

gl.drawArrays(gl.POINTS, 0, 6 * uPieces * vPieces );

球面點
三角面片效果:

gl.drawArrays(gl.TRIANGLES, 0, 6 * uPieces * vPieces );

在這裏插入圖片描述

2 紋理

思路和上面一致,將二維紋理座標映射到WebGL座標即可
效果如下
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章