国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

一起學 WebGL:三角形加上漸變色

開發 前端
本節講了Varying 的能力:將頂點著色器中的變量傳遞給片元著色器。并演示了使用兩個緩沖區對象,位置數據和顏色數據,以及將它們組合成一個緩沖區對象的實現。

大家好,我是前端西瓜哥。之前教大家繪制一個紅色的三角形,這次我們來畫個有漸變的三角形。

原來的寫法,顏色是在片元著色器中寫死的,這次我們來像傳頂點數據一樣,聲明一個顏色數據傳遞過去。

顏色需要在片元著色器中賦值給內部變量 gl_FragColor,但 attribute 動態類型卻不能在片元著色器中使用。

這時候就要用到一個新的類型 varying 了。(意思為:“變化的“)

varying 用于從頂點著色器中將變量傳遞到片元著色器中

兩個緩沖區對象的寫法

著色器代碼:

const vertexShaderSrc = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
 gl_Position = a_Position;
 v_Color = a_Color;
}
`;

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

這里我們需要在兩種著色器中同時聲明 varing 變量,后面的類型也必須是相同的 vec4,變量名也要一致,只能說是完全相同了。

頂點著色器中需要通過 v_Color = a_Color; 賦值。然后在片元著色器中,再將同步過來的 v_Color 賦值給 gl_FragColor。

然后是新增的顏色數組的聲明,以及對應緩存區的創建。

/**** 顏色數據 ****/
// prettier-ignore
const colors = new Float32Array([
  1, 0, 0, // 紅色
  0, 1, 0, // 綠色
  0, 0, 1, // 藍色
])
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
const a_Color = gl.getAttribLocation(gl.program, "a_Color");
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Color);

貼一下完整代碼:

/** @type {HTMLCanvasElement} */
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");

const vertexShaderSrc = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
 gl_Position = a_Position;
 v_Color = a_Color;
}
`;

const fragmentShaderSrc = `
precision mediump 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 vertices = new Float32Array([
  0, 0.5,  // 第一個點
  -0.5, -0.5,  // 第二個點
  0.5, -0.5,  // 第三個點
]);

// 創建緩存對象
const vertexBuffer = gl.createBuffer();
// 綁定緩存對象到上下文
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 向緩存區寫入數據
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 獲取 a_Position 變量地址
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
// 將緩沖區對象分配給 a_Position 變量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

// 允許訪問緩存區
gl.enableVertexAttribArray(a_Position);

/**** 顏色數據 ****/
// prettier-ignore
const colors = new Float32Array([
  1, 0, 0, // 紅色
  0, 1, 0, // 綠色
  0, 0, 1, // 藍色
])
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
const a_Color = gl.getAttribLocation(gl.program, "a_Color");
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Color);

/*** 繪制 ***/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

demo 地址:

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

渲染結果:

圖片

我們其實只是給三個頂點設置了紅、綠、藍三個顏色,然后 WebGL 會基于它們計算出中間的過內插顏色,將它們填充滿三個點圍成區域的像素點。

單緩沖區的實現

前面的實現用了兩個緩沖區對象分別保存位置信息和顏色信息。

但實際上可以將它們組合在一起,讓數據更緊湊放在一個緩沖區里。

浮點數數組為:

// prettier-ignore
const verticesColors = new Float32Array([
  0, 0.5, 1, 0, 0,  // 點 1 的位置和顏色信息
  -0.5, -0.5, 0, 1, 0,  // 點 2
  0.5, -0.5, 0, 0, 1,  // 點 3
]);

然后是和前一種寫法有一些不同的地方:

// 每個數組元素的字節數
const SIZE = verticesColors.BYTES_PER_ELEMENT;

// 獲取 a_Position 變量地址
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, SIZE * 5, 0);
gl.enableVertexAttribArray(a_Position);

const a_Color = gl.getAttribLocation(gl.program, "a_Color");
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, SIZE * 5, SIZE * 2);
gl.enableVertexAttribArray(a_Color);

主要是 gl.vertexAttribPointer 方法的最后兩個參數 stride 和 offset。

我們看下面這個:

gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, SIZE * 5, SIZE * 2);

stride 為 SIZE * 5(單位為字節,所以要乘以一個數組元素的字節大小),表示 5 個數組元素為一趟,然后 offset 為 SIZE  * 2,表示從第 2 個元素,取 3 個元素作為這一趟的數據內容。

完整代碼實現:

/** @type {HTMLCanvasElement} */
const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");

const vertexShaderSrc = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
 gl_Position = a_Position;
 v_Color = a_Color;
}
`;

const fragmentShaderSrc = `
precision mediump 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([
  0, 0.5, 1, 0, 0,  // 點 1 的位置和顏色信息
  -0.5, -0.5, 0, 1, 0,  // 點 2
  0.5, -0.5, 0, 0, 1,  // 點 3
]);
// 每個數組元素的字節數
const SIZE = verticesColors.BYTES_PER_ELEMENT;

// 創建緩存對象
const vertexColorBuffer = gl.createBuffer();
// 綁定緩存對象到上下文
gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
// 向緩存區寫入數據
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

// 獲取 a_Position 變量地址
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, SIZE * 5, 0);
gl.enableVertexAttribArray(a_Position);

const a_Color = gl.getAttribLocation(gl.program, "a_Color");
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, SIZE * 5, SIZE * 2);
gl.enableVertexAttribArray(a_Color);

/*** 繪制 ***/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

demo 地址:

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

結尾

本節講了 varying 的能力:將頂點著色器中的變量傳遞給片元著色器。并演示了使用兩個緩沖區對象,位置數據和顏色數據,以及將它們組合成一個緩沖區對象的實現。

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

2023-04-17 09:01:01

WebGL繪制三角形

2023-11-01 07:51:15

WebGPU3D 圖形

2016-10-20 13:36:28

WebRTC瀏覽器服務器

2021-10-19 10:09:21

三角形個數數組

2022-03-16 14:27:49

CSS三角形前端

2021-08-29 18:32:18

CSS

2020-12-09 08:34:24

css生成器設計師

2023-04-26 07:42:16

WebGL圖元的類型

2024-02-20 18:30:53

CSS屬性邊框

2022-09-14 15:17:26

ArkUI鴻蒙

2023-05-04 08:48:42

WebGL復合矩陣

2023-06-26 15:14:19

WebGL紋理對象學習

2023-04-12 07:46:24

JavaScriptWebGL

2023-03-29 07:31:09

WebGL坐標系

2021-07-16 05:59:27

CSS 技巧帶圓角的三角形

2013-09-26 13:43:13

iOS開發OpenGL ES教程圖元

2018-03-02 15:54:37

三角形主機比特幣

2021-04-15 06:02:50

CSS 三角形技巧

2023-05-16 07:44:03

紋理映射WebGL

2023-05-31 20:10:03

WebGL繪制立方體
點贊
收藏

51CTO技術棧公眾號

国产一二区在线| 国产精品乱战久久久| 综合精品久久久| 日本a级片在线观看| 综合久久久久| 91精品视频免费| 国产精品久久精品国产| 精品视频在线观看免费观看| 日韩hd视频在线观看| 国产黄视频网站| 成人免费视频免费观看| 欧美日韩三区四区| 欧美一区二区三区另类| 国产精品久久久久久超碰 | 国内精品久久久久影院薰衣草 | cao在线观看| 国产白丝精品91爽爽久久| 正在播放91九色| 精品亚洲国内自在自线福利| 日本视频一区二区不卡| 美女黄色成人网| 欧美二区三区| 日本伊人午夜精品| 在线成人性视频| 国产91精品一区二区麻豆亚洲| 国产精品久久久久久久久电影网| 精品一区二区三区在线观看| 欧美亚洲色图视频| www.99精品| 老头吃奶性行交视频| 日韩理论在线观看| 99re6热在线精品视频播放| 色丁香久综合在线久综合在线观看| 成黄免费在线| 亚洲国产精品大全| 24小时成人在线视频| 欧美久久精品一级黑人c片| 噜噜噜天天躁狠狠躁夜夜精品 | 老司机在线精品视频| 国产精品综合网站| 国产美女一区| 成人在线播放网址| 欧美极品少妇xxxxⅹ高跟鞋| 欧美xxxxxxxxx59| 在线一区二区三区| 欧美1—12sexvideos| 在线日韩欧美视频| 亚洲深夜福利在线观看| 国产福利久久| 国产一区二区三区免费看| 91精品91久久久中77777老牛| 亚洲欧洲日产国码二区| 日韩porn| 亚洲精品乱码久久久久久按摩观| 亚洲午夜精品| 国产精品麻豆免费版| 久久国产欧美日韩精品| 亚洲欧美在线精品| 欧美日韩免费观看一区三区| 韩国精品主播一区二区在线观看 | 在线日本欧美| 国产福利精品在线| 蜜桃视频一区二区| 激情综合网五月激情 | 日韩视频在线视频| 又紧又大又爽精品一区二区| 一本一道波多野毛片中文在线| 亚洲成年人在线| 日韩视频在线直播| 国产精品免费看一区二区三区| 国产盗摄女厕一区二区三区| 一级香蕉视频在线观看| 亚洲人成网7777777国产| 精品国精品国产自在久国产应用| 亚洲精品第一区二区三区| 日韩一区在线看| 99爱在线观看| 成人午夜高潮视频| 不卡电影免费在线播放一区| 黄色的视频在线免费观看| www亚洲精品| 国产一级一区二区| 一级片视频免费观看| 亚洲精品在线免费播放| 禁果av一区二区三区| 2018中文字幕第一页| 欧美日韩激情一区二区三区| 久久精品凹凸全集| 久久人妻无码一区二区| 在线亚洲高清视频| 老牛国内精品亚洲成av人片| 91制片厂免费观看| 欧美在线free| 在线看片地址| 亚洲国产一区二区三区在线播 | 又黄又爽在线观看| 色88888久久久久久影院野外| 国产精品亲子伦av一区二区三区| 成人午夜激情免费视频| 久久久99免费| heyzo一区| 99www免费人成精品| 国产日韩av一区| 色一区二区三区| 国内精品国语自产拍在线观看| 亚洲视频综合在线| 亚洲精品aaa| 亚洲人成77777| 欧美日韩在线综合| 狠狠综合久久av一区二区蜜桃| 久久国产精品网| 欧美电视剧在线看免费| 伊人成综合网| www.97.| 欧美精品制服第一页| 国产一区999| av小说在线播放| 精品一区二区三区免费毛片| 一区二区三区四区亚洲| 激情久久一区二区| 最近看过的日韩成人| 51久久夜色精品国产麻豆| 天天做天天爱天天综合网2021| www.1024| 91成人在线播放| 91免费精品国自产拍在线不卡| 欧美极品影院| 永久免费在线看片视频| 亚洲国产女人aaa毛片在线| 日日夜夜精品视频天天综合网| 大地资源网3页在线观看| 成人激情视频在线播放| 精品美女久久久久久免费| 国产精品99久久久久久动医院| 中文字幕在线观看| 99在线视频播放| 欧美日韩免费高清一区色橹橹| 国产精品多人| 国产视频第一页在线观看| 国产精品免费小视频| 亚洲va欧美va国产va天堂影院| 国产影视一区| 亚洲伦理在线| 国产伦精品一区二区三区四区视频 | 久久久久国产精品| 李宗瑞系列合集久久| 日本久久久久久久久| 依依成人综合视频| 欧美成人直播| av网站大全在线观看| 欧美成人蜜桃| 亚洲第一福利网| 国产成人激情av| 一区二区三区四区精品视频| 1区不卡电影| 成人欧美一区二区| 亚洲高清免费观看高清完整版| 国产成人av资源| 亚洲精品一区二区三区在线| 成r视频免费观看在线播放| 好吊色欧美一区二区三区四区| 亚洲国产精品女人久久久| 久久免费精品国产久精品久久久久| 亚洲另类av| 欧美日韩xx| 男女猛烈激情xx00免费视频| 欧美中文字幕在线观看| 欧美日韩成人高清| 99久久精品情趣| 成人直播大秀| 男女在线视频| 18成人免费观看视频漫画| 国产精选在线观看91| 一区二区三区四区视频| 一区二区三区欧美亚洲| 日韩电影在线观看一区| aiss精品大尺度系列| 国产午夜精品一区理论片| 性欧美18一19内谢| 欧美性一区二区三区| 欧美日韩成人综合| 97精品视频在线观看自产线路二| 色综合咪咪久久网| 国产亚洲成av人片在线观看| 久久99爱视频| 深夜福利成人| 国产91精品久久久久久| 欧美精品国产精品| 中文字幕不卡三区| 国产日韩一区| 一区二区导航| 九九九伊在线综合永久| 可以在线观看的黄色| 欧美韩国日本在线| 动漫3d精品一区二区三区 | 丁香六月综合| 免费视频爱爱太爽了| 日本高清视频在线观看| 国产精品无av码在线观看| 日韩禁在线播放|