精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一起學 WebGL:繪制立方體

開發 前端
現在我們來繪制一個立方體,其實本質和繪制二維圖形是一樣,也是繪制三角形,只是繪制很多個,然后組合起來,作為立方體的幾個面,拼在一起就是一個立方體了。

大家好,我是前端西瓜哥。

之前我們繪制三角形,是一個二維的圖形。

現在我們來繪制一個立方體,其實本質和繪制二維圖形是一樣,也是繪制三角形,只是繪制很多個,然后組合起來,作為立方體的幾個面,拼在一起就是一個立方體了。

繪制三角形,我們用的 API 是:

gl.drawArrays(gl.TRIANGLES, 0, n);

那畫一個立方體,假設選擇 gl.TRIANGLE_FAN 圖元模式,也就是畫 6 個面,每個面有 4 個點。所以我們需要定義 24 個點。

這其實重復定義了頂點,因為一個立方體也就 8 個點,數據是有冗余的。

WebGL 提供了 gl.drawElements() 方法,通過索引值映射的方式來解決這個問題。

首先定義立方體的 8 個頂點(我們命名為 v0 到 v7)的位置和顏色。

const verticesColors = new Float32Array([
  1, 1, 1,     1, 1, 1, // 點 0 白
  -1, 1, 1,    1, 0, 1, // 點 1 品紅
  -1, -1, 1,   1, 0, 0, // 點 2 紅
  1, -1, 1,    1, 1, 0, // 點 3 黃

  1, -1, -1,   0, 1, 0, // 點 4 綠色
  1, 1, -1,    0, 1, 1, // 點 5 青色
  -1, 1, -1,   0, 0, 1, // 點 6 藍色
  -1, -1, -1,  0, 0, 0, // 點 7 黑色
]);

圖片

然后用索引值構造好 6 個面,每個面 2 個三角形:

const indices = new Uint8Array([
  0, 1, 2, 0, 2, 3, // 正面
  0, 3, 4, 0, 4, 5, // 右面
  0, 5, 6, 0, 6, 1, // 上面
  1, 6, 7, 1, 7, 2, // 左面
  7, 4, 3, 7, 3, 2, // 下面
  4, 7, 6, 4, 6, 5, // 背面
]);

和頂點數據類似,索引值也要創建一個緩沖區,并進行綁定,綁定目標變成了 gl.ELEMENT_ARRAY_BUFFER 上。

const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

最后調用 gl.drawElements 方法進行繪制。這里要傳入 indices 數組的長度,WebGL 就會讀取索引值得到對應的頂點信息去一個個繪制三角形啦。

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);

繪制結果:

圖片

完整代碼:

// Create a cube
//    v6----- v5
//   /|      /|
//  v1------v0|
//  | |     | |
//  | |v7---|-|v4
//  |/      |/
//  v2------v3

/** @type {HTMLCanvasElement} */
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const infoDiv = document.createElement('div');
document.body.appendChild(infoDiv);

const vertexShaderSrc = `
attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_ViewMatrix;  // 視圖矩陣
uniform mat4 u_ProjMatrix; // 正射投影矩陣
mat4 u_MvpMatrix = u_ProjMatrix * u_ViewMatrix;
varying vec4 v_Color;
void main() {
 gl_Position = u_MvpMatrix * a_Position;
 v_Color = a_Color;
}
`;

const fragmentShaderSrc = `
precision highp float;
varying vec4 v_Color;
void main() {
  gl_FragColor = v_Color;
}
`;

/**** 渲染器生成處理 ****/
// 創建頂點渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
// 創建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
// 程序對象
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
gl.program = program;

// prettier-ignore
const verticesColors = new Float32Array([
  1, 1, 1,     1, 1, 1, // 點 0 白
  -1, 1, 1,    1, 0, 1, // 點 1 品紅
  -1, -1, 1,   1, 0, 0, // 點 2 紅
  1, -1, 1,    1, 1, 0, // 點 3 黃

  1, -1, -1,   0, 1, 0, // 點 4 綠色
  1, 1, -1,    0, 1, 1, // 點 5 青色
  -1, 1, -1,   0, 0, 1, // 點 6 藍色
  -1, -1, -1,  0, 0, 0, // 點 7 黑色
]);

// prettier-ignore
const indices = new Uint8Array([
  0, 1, 2, 0, 2, 3, // 正面
  0, 3, 4, 0, 4, 5, // 右面
  0, 5, 6, 0, 6, 1, // 上面
  1, 6, 7, 1, 7, 2, // 左面
  7, 4, 3, 7, 3, 2, // 下面
  4, 7, 6, 4, 6, 5, // 背面
]);

// 每個數組元素的字節數
const SIZE = verticesColors.BYTES_PER_ELEMENT;
// 創建緩存對象
const vertexColorBuffer = gl.createBuffer();
const indexBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

// 獲取 a_Position 變量地址
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
const a_Color = gl.getAttribLocation(gl.program, 'a_Color');
/****** 正射投影 ******/
const u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');

// prettier-ignore
const viewMatrix = createViewMatrix(
  3, 4, 8, // 觀察點
  0, 0, 0, // 視點
  0, 1, 0 // 上方向
)
gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix);

/****** 正射投影 ******/
const u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
// prettier-ignore
const projMatrix = createPerspective(
  30, canvas.width / canvas.height, 1, 100
)
gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix);

gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, SIZE * 6, 0);
gl.enableVertexAttribArray(a_Position);

gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, SIZE * 6, SIZE * 3);
gl.enableVertexAttribArray(a_Color);

/*** 繪制 ***/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.enable(gl.DEPTH_TEST); // 啟動深度檢測,處理錯誤的像素覆蓋問題

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// 繪制三角形
// gl.drawArrays(gl.TRIANGLES, 0, 8);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);

/************ 后面都是一些工具類方法 ******/

/**** 構造視圖矩陣 ****/
function createViewMatrix(eyeX, eyeY, eyeZ, atX, atY, atZ, upX, upY, upZ) {
  const normalize = (v) => {
    const length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
    return [v[0] / length, v[1] / length, v[2] / length];
  };
  const subtract = (v1, v2) => {
    return [v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]];
  };
  const cross = (v1, v2) => {
    return [
      v1[1] * v2[2] - v1[2] * v2[1],
      v1[2] * v2[0] - v1[0] * v2[2],
      v1[0] * v2[1] - v1[1] * v2[0],
    ];
  };

  const zAxis = normalize(subtract([eyeX, eyeY, eyeZ], [atX, atY, atZ]));
  const xAxis = normalize(cross([upX, upY, upZ], zAxis));
  const yAxis = normalize(cross(zAxis, xAxis));

  return new Float32Array([
    xAxis[0],
    yAxis[0],
    zAxis[0],
    0,
    xAxis[1],
    yAxis[1],
    zAxis[1],
    0,
    xAxis[2],
    yAxis[2],
    zAxis[2],
    0,
    -(xAxis[0] * eyeX + xAxis[1] * eyeY + xAxis[2] * eyeZ),
    -(yAxis[0] * eyeX + yAxis[1] * eyeY + yAxis[2] * eyeZ),
    -(zAxis[0] * eyeX + zAxis[1] * eyeY + zAxis[2] * eyeZ),
    1,
  ]);
}

function angleToRadian(angle) {
  return (Math.PI * angle) / 180;
}

/***** 構建透視矩陣 *****/
function createPerspective(fov, aspect, near, far) {
  fov = angleToRadian(fov); // 角度轉弧度
  const f = 1.0 / Math.tan(fov / 2);
  const nf = 1 / (near - far);
  // prettier-ignore
  return new Float32Array([
    f / aspect, 0, 0, 0,
    0, f, 0, 0,
    0, 0, (far + near) * nf, -1,
    0, 0, 2 * far * near * nf, 0,
  ]);
}

線上體驗 demo:

https://codesandbox.io/s/upx8yz?file=/index.js。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2023-04-12 07:46:24

JavaScriptWebGL

2023-05-16 07:44:03

紋理映射WebGL

2023-04-11 07:48:32

WebGLCanvas

2023-04-17 09:01:01

WebGL繪制三角形

2023-05-04 08:48:42

WebGL復合矩陣

2023-04-26 07:42:16

WebGL圖元的類型

2023-06-26 15:14:19

WebGL紋理對象學習

2023-03-29 07:31:09

WebGL坐標系

2023-04-13 07:45:15

WebGL片元著色器

2023-05-17 08:28:55

2023-04-27 08:27:29

WebGL變形矩陣

2023-03-02 07:44:39

pixijsWebGL

2023-02-22 09:27:31

CanvasWebGL

2023-05-08 07:29:48

WebGL視圖矩陣

2022-11-29 16:35:02

Tetris鴻蒙

2022-12-02 14:20:09

Tetris鴻蒙

2023-03-30 09:32:27

2022-11-14 17:01:34

游戲開發畫布功能

2019-07-16 16:05:51

PythonScribusRGB

2023-05-06 07:23:57

點贊
收藏

51CTO技術棧公眾號

妺妺窝人体色www聚色窝仙踪| 别急慢慢来1978如如2| 色噜噜在线播放| 欧美性xxx| 久久综合九色综合欧美就去吻| 国产精品jizz在线观看麻豆| 波多野结衣一二三四区| 欧美性受ⅹ╳╳╳黑人a性爽| 国产福利精品一区| 国产91精品久久久久久久| 91麻豆精品国产91久久综合| 日韩综合一区二区三区| 欧美午夜女人视频在线| 日韩资源av在线| 999国产精品视频免费| 裸体一区二区| 欧美激情二区三区| 在线视频一二区| 91桃色在线| 亚洲欧洲无码一区二区三区| 精品国产乱码久久久久久108| 影音先锋国产在线| 亚洲一区二区伦理| 亚洲第一精品福利| 欧美激情第3页| 自由日本语热亚洲人| 亚洲精品高清在线观看| 欧美性大战久久久久| 成人无码一区二区三区| 久久爱www久久做| 国产91亚洲精品| xxxxxx国产| 亚洲精品mv在线观看| 欧美xxxxhdvideosex| 国产精品久久久久久户外露出 | 国产精品男女视频| 欧美日韩一区自拍| 久久视频在线直播| 国精产品视频一二二区| 国产在线观看91一区二区三区 | av大片在线观看| 91蜜桃在线观看| 精品欧美一区二区精品久久| 成人毛片在线精品国产| 国产成人精品免费看| 亚洲bt欧美bt日本bt| 91免费视频播放| 小处雏高清一区二区三区| 欧洲av一区二区嗯嗯嗯啊| www.四虎成人| 三上悠亚国产精品一区二区三区| 午夜在线成人av| 国产 日韩 欧美在线| 亚洲日本香蕉视频| 99久久免费精品| 精品毛片久久久久久| 午夜黄色小视频| 久久一区二区视频| 日本10禁啪啪无遮挡免费一区二区| 香蕉久久国产av一区二区| 91看片淫黄大片一级| 亚洲乱码中文字幕综合| 最近2019中文字幕mv免费看| aaaaa级少妇高潮大片免费看| 人人网欧美视频| 亚洲男人的天堂在线| 欧美18—19性高清hd4k| 欧美精品系列| www.亚洲人.com| 青青草手机视频在线观看| 黄色工厂这里只有精品| 久久久免费av| 区一区二在线观看| 免费在线欧美视频| 成人免费高清完整版在线观看| 国产精品欧美久久久久天天影视| 国产精品一区二区久久精品爱涩| 成人在线免费网站| 毛片在线免费视频| 久久福利一区| 国产精品视频精品| h狠狠躁死你h高h| av电影在线观看一区| 欧美午夜欧美| 主播国产精品| 欧美国产精品一区| 青青草原网站在线观看| av中文在线资源| 91福利视频在线| 亚洲欧美福利视频| 欧美少妇一区| 91亚洲天堂| 精品免费在线视频| 亚洲精品第三页| 国产欧美一区二区三区米奇| 在线精品视频小说1| 最新天堂在线视频| 秋霞在线一区| 日韩小视频网址| 国产精品成人久久| 人人狠狠综合久久亚洲| 91入口在线观看| 国产youjizz在线| 亚洲综合色网站| 一道本视频在线观看| 亚洲精品a区| 中文字幕在线成人| 日本视频免费在线| 欧美日韩xx| 国产成人午夜精品影院观看视频 | 国产精品高清亚洲| 国产特级淫片高清视频| 亚洲网站免费| 亚洲无亚洲人成网站77777| 久草免费在线观看视频| 免费成人美女在线观看.| 粉嫩av一区二区三区免费观看| 成人激情电影在线看| 欧美日韩亚洲国产一区| 欧美人与性动交α欧美精品| 日韩影院二区| 热草久综合在线| 国产 日韩 欧美 精品| 综合久久久久久久| 成人免费视频久久| 奇米777国产一区国产二区| 蜜臀久久99精品久久久久久宅男 | 亚洲欧洲午夜一线一品| 久久精品欧美一区二区| 国产精品一区在线观看你懂的| 日韩欧美亚洲在线| 伊人网在线播放| 精品成人a区在线观看| www.5588.com毛片| 蜜桃91丨九色丨蝌蚪91桃色| 日韩av电影免费播放| 松下纱荣子在线观看| 亚洲精品一区二区三区精华液 | 东热在线免费视频| 日韩欧美aaa| 午夜免费福利影院| 1024日韩| 久久99精品久久久久久三级| a√中文在线观看| 精品国产一区二区三区av性色| 一区二区视频免费看| 国产在线播精品第三| 在线视频福利一区| 只有精品亚洲| 久久综合电影一区| 国产丰满美女做爰| 亚洲精品视频在线观看网站| 中文字幕55页| 午夜精品毛片| 999国内精品视频在线| 欧美性受ⅹ╳╳╳黑人a性爽| 精品国产凹凸成av人导航| 欧美成人精品激情在线视频| 极品少妇一区二区| 亚洲最大成人网色| 国产精品久久麻豆| 精品捆绑美女sm三区| 舐め犯し波多野结衣在线观看| 亚洲欧美网站| 亚洲第一综合| 97超碰免费在线| 亚洲精品天天看| 久久爱一区二区| 国内久久精品视频| 欧美亚洲色图视频| 婷婷综合福利| 国产精品毛片a∨一区二区三区|国| 在线免费看av| 精品国产3级a| 最近中文字幕在线观看| 亚洲天堂成人网| 欧美一区二区免费在线观看| 久久久久中文| 亚洲成年人专区| 国产香蕉精品| 国产精品久久久久久久久久新婚 | 欧美丝袜丝交足nylons172| 91免费看国产| 日本三级一区| 日韩亚洲在线观看| 欧美 日韩 国产 精品| 一本久道中文字幕精品亚洲嫩| a级黄色免费视频| 大尺度一区二区| 中文字幕国产传媒| 国产精品v亚洲精品v日韩精品 | 欧美日韩一区二区国产| 欧美另类高清视频在线| www.久久久.com| 欧美一级大片在线观看| 免费高清完整在线观看| 日韩国产高清污视频在线观看| 亚洲一区二区影视| 性做久久久久久免费观看欧美| 四虎国产精品成人免费入口| 国产风韵犹存在线视精品| 精品一卡二卡三卡| 在线观看日韩av电影| 亚洲免费在线精品一区| 久久精品国产亚洲5555| 91探花福利精品国产自产在线 | 在线观看国产精品网站| 精品少妇久久久| 国产精品天天看| 精品中文字幕在线播放| 国产一区二区免费视频| 国产高清精品在线观看| 看全色黄大色大片免费久久久| 国产精品极品在线| 国产福利片在线观看| 久久天天躁狠狠躁夜夜爽蜜月| 日韩欧美在线观看一区二区| 日韩精品中文字幕在线一区| 中文字幕在线观看第二页| 欧美日韩亚洲视频一区| 精品一级少妇久久久久久久| 综合久久一区二区三区| 亚洲综合欧美综合| 91丨porny丨首页| 折磨小男生性器羞耻的故事| 国产尤物一区二区在线| 午夜激情av在线| 日韩精品免费专区| 久章草在线视频| 久久免费国产| 男人天堂1024| 99视频精品| 日韩理论片在线观看| 先锋影音国产精品| 精品国产乱码久久久久久108| 中文字幕一区二区三区中文字幕 | 欧美一级全黄| 国产日韩欧美综合精品| 成人知道污网站| 国产成人精品一区二区三区福利| 国产专区精品| 777777777亚洲妇女| 久草在线资源站手机版| 韩国19禁主播vip福利视频| 三级资源在线| 国色天香2019中文字幕在线观看| 天堂8中文在线| 欧美激情精品久久久久久蜜臀| 亚洲h片在线看| 久久久人成影片一区二区三区观看 | 日本免费a视频| 精品91在线| 久久综合色视频| 久久综合狠狠| 欧美日韩在线观看不卡| 国产中文一区二区三区| 国产91在线免费观看| 成人午夜大片免费观看| 粉嫩av懂色av蜜臀av分享| 91麻豆文化传媒在线观看| 无码人妻精品一区二区中文| 国产精品―色哟哟| 91在线播放观看| 精品福利樱桃av导航| 波多野结衣一区二区在线| 欧美日韩一卡二卡| www.色亚洲| 精品无人区太爽高潮在线播放| 狠狠色伊人亚洲综合网站l | 国产在线xxx| 91av视频在线免费观看| 日韩欧美2区| 午夜精品久久久久久99热| 久久影院午夜精品| 国产精品pans私拍| 国产精品高清一区二区| 国产经典一区二区三区| 亚洲亚洲免费| 国产传媒一区二区三区| 婷婷精品视频| 黄色免费高清视频| 日韩视频二区| 五月天亚洲视频| 成人免费毛片高清视频| 国产aⅴ激情无码久久久无码| 亚洲天堂免费在线观看视频| 综合激情网五月| 欧美精品电影在线播放| 精品国产www| 日韩网站在线看片你懂的| 四虎国产精品永远| 久久九九热免费视频| 欧美激情免费| 91禁外国网站| 电影一区中文字幕| 蜜桃成人在线| 亚洲人成伊人成综合图片| 亚洲一区精品视频| 亚洲免费精品| av在线网站免费观看| 久久蜜桃av一区二区天堂| 外国一级黄色片| 色拍拍在线精品视频8848| а√中文在线资源库| 在线不卡国产精品| 99riav视频在线观看| 亚洲综合一区二区不卡| 精品免费在线| 欧美一级在线看| 成人免费视频免费观看| 美国黄色片视频| 在线这里只有精品| 五月婷婷狠狠干| 高清视频欧美一级| 久久av网站| 正在播放国产精品| 丝袜诱惑制服诱惑色一区在线观看| aaa黄色大片| 中文字幕一区二区三区视频| 波多野结衣高清视频| 亚洲韩国欧洲国产日产av| 中文字幕资源网在线观看| 国产精品网红直播| 精品久久久久久久久久久下田| 免费看国产曰批40分钟| 国产91精品在线观看| 综合五月激情网| 欧美精品 日韩| 欧美成人三区| 成人黄色av免费在线观看| 区一区二视频| 国产wwwxx| 国产女人水真多18毛片18精品视频 | 国产精品一区二区在线| 国产成人影院| 久久久久狠狠高潮亚洲精品| 91在线精品一区二区| 久草国产精品视频| 亚洲国产精品成人av| 91美女精品| 久久国产精品免费一区| 一本色道久久| 爱爱的免费视频| 欧美性猛交xxxx乱大交3| 三级av在线播放| 日韩美女主播视频| 国产一区不卡| 亚洲 欧美 日韩系列| 亚洲国产精品精华液ab| 糖心vlog精品一区二区| 色偷偷偷亚洲综合网另类| 91大神在线观看线路一区| 亚洲一二三区在线| 久久99热狠狠色一区二区| √天堂中文官网8在线| 91精品国产麻豆| 牛牛在线精品视频| 精品国产乱码久久久久| 首页亚洲欧美制服丝腿| 少妇一级黄色片| 91精品国产91久久久久久一区二区| 黄色成人在线观看| 国产精品xxx在线观看www| 亚洲少妇在线| 欧美一区二区三区粗大| 制服丝袜激情欧洲亚洲| 欧美性video| 欧美日韩亚洲综合一区二区三区激情在线| 久久狠狠一本精品综合网| 久久午夜精品视频| 欧美一区二区三级| 国产一二在线播放| 手机成人在线| 国产成人精品免费视频网站| av大全在线观看| 中文字幕自拍vr一区二区三区| 精品91福利视频| 北条麻妃在线视频观看| 中文字幕精品—区二区四季| 国产成人av免费看| 91大神福利视频在线| 欧美大黑bbbbbbbbb在线| 中文字幕乱妇无码av在线| 色先锋aa成人| av在线免费网站| 欧美成ee人免费视频| 韩国视频一区二区| 日韩欧美一级视频| 日韩在线视频二区| 九色丨蝌蚪丨成人| www.超碰97.com| 婷婷综合久久一区二区三区| 91精彩视频在线观看| 国产伦精品一区二区三区照片| 蜜臂av日日欢夜夜爽一区| 日本污视频在线观看| 俺也去精品视频在线观看| 日韩有码av| 日韩大尺度视频| 欧美日韩情趣电影|