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座標即可
效果如下