成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一起學 WebGL:動態繪制點

開發 前端
這節課我們會通過 JavaScript 給著色器動態提供數據,而不需要重新編譯著色器。

大家好,我是前端西瓜哥。上一篇文章講解了如何繪制一個點。但這個點的信息是寫死在渲染器源碼中的,也就是硬編碼。

這是系列文章,如果你是初學者,你需要看上一篇文章才好理解這節課的內容。

??《一起學 WebGL:繪制一個點》??

如果我們要頻繁地改變點的位置去繪制,根據我們之前學到的知識點,那只能通過替換整個著色器代碼字符串,不斷地編譯的方式去修改了,非常不便。

這節課我們會通過 JavaScript 給著色器動態提供數據,而不需要重新編譯著色器。

靜態繪制點

先貼上上篇文章的靜態寫法。

demo 地址:

https://codesandbox.io/s/webgl-hui-zhi-yi-ge-dian-2-bpwz8p。

/**
* wegbl 繪制一個點
*/

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

const vertexShaderSrc = `
attrs
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
gl_PointSize = 20.0;
}
`;

const fragmentShaderSrc = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

/**** 渲染器生成處理 ****/
// 創建頂點渲染器
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;

/** 畫布繪制 **/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪制點
gl.drawArrays(gl.POINTS, 0, 1);

渲染結果:

圖片

外部傳遞點的位置信息

下面我們希望頂點著色器的點的坐標可以通過 JavaScript 動態地修改。

加入 attribute 變量

修改頂點著色器的代碼:

const vertexShaderSrc = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
gl_PointSize = 20.0;
}
`;

這里西瓜哥我將原本的 vec4 類型的寫死的顏色值,換成了一個變量 a_Position。attribute 是存儲限定符,表示變量是 attribute 類型,它用于描述頂點數據,值可以通過外部傳遞被修改。后面我們從外部拿到這個變量,傳入我們想要的值。

vec4 則是變量類型,表示一個有四個分量的矢量。

變量通常會用 a_ 作為前綴,表示該變量是 attribute 類型。

外部修改 attribute

然后是在 JavaScript 代碼中獲取這個 a_Position 變量,并傳一個值給它。

const a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttrib3f(a_Position, 0, 0.5, 0);

第一行 gl.getAttribLocation 方法的作用,是從 gl.program 程序對象中,取出一個名為 "a_Position" 的 attribute 變量的地址。如果找到,會返回一個大于等于 0 的值,找不到會返回  -1。

第二行,gl.vertexAttrib3f 就是根據地址給 a_Position 變量賦予值。a_Position 是 4 個浮點數組成的矢量類型,我們這里并沒有傳 4 個值,只傳了 3 個。最后一個值對坐標系來說并無意義,但在矩陣變換時會用到,不提供會被自動填充為默認的 1.0。

你也可以用 gl.vertexAttrib4f 提供完成的 4 個浮點數,或者用 gl.vertexAttrib1f 或 gl.vertexAttrib2f 提供第一個或前兩個浮點數。缺少的 y、z 默認會用 0.0,z 則使用 1.0。

這里我們給 y 設置了 0.5,渲染結果為:

圖片

關于坐標系的文章

《??一起學 WebGL:坐標系??》

補充一下 WebGL 的坐標系圖示:

圖片

完整代碼:

/**
* wegbl 繪制一個點
*/

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

const vertexShaderSrc = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
gl_PointSize = 20.0;
}
`;

const fragmentShaderSrc = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

/**** 渲染器生成處理 ****/
// 創建頂點渲染器
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;

/** 修改著色器的 attribute */
const a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttrib3f(a_Position, 0, 0.5, 0);

/** 畫布繪制 **/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪制點
gl.drawArrays(gl.POINTS, 0, 1);

demo 地址:

https://codesandbox.io/s/webgl-dong-tai-hui-zhi-dian-5cdped?file=/index.js。

不斷修改位置信息

下面我們用一個定時器,不斷地修改點的位置。

代碼實現:

/**
* webgl 動態繪制點 + 定時器
*/

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

const vertexShaderSrc = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
gl_PointSize = 20.0;
}
`;

const fragmentShaderSrc = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

/**** 渲染器生成處理 ****/
// 創建頂點渲染器
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;

/** 修改著色器的 attribute */
const a_Position = gl.getAttribLocation(gl.program, "a_Position");

let x = -1;
let y = -1;

setInterval(() => {
gl.vertexAttrib3f(a_Position, x, y, 0);
x += 0.25;
if (x > 1) x = -1;
y += 0.25;
if (y > 1) y = -1;

/** 畫布繪制 **/
// 清空畫布,并指定顏色
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪制點
gl.drawArrays(gl.POINTS, 0, 1);
}, 180);

在定時器中,我們不斷地修用 gl.vertexAttrib3f 修改點的位置,并重繪畫布。

demo 地址:

https://codesandbox.io/s/webgl-dong-tai-hui-zhi-dian-ding-shi-qi-gnjx3t。

渲染效果:

圖片

結尾

我是前端西瓜哥,歡迎關注我,學習更多前端知識。

這里布置一個小練習:動態修改點的大小,這次要用 float 類型,并對應使用 g1.vertexAttriblf 傳遞值。

答案在:https://codesandbox.io/s/g4ft9m

下一節我們將學習如何動態修改片元著色器中點的顏色。

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

2023-04-11 07:48:32

WebGLCanvas

2023-05-16 07:44:03

紋理映射WebGL

2023-05-31 20:10:03

WebGL繪制立方體

2023-04-13 07:45:15

WebGL片元著色器

2023-04-17 09:01:01

WebGL繪制三角形

2023-03-29 07:31:09

WebGL坐標系

2023-05-04 08:48:42

WebGL復合矩陣

2023-06-26 15:14:19

WebGL紋理對象學習

2023-04-26 07:42:16

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-12-02 14:20:09

Tetris鴻蒙

2022-11-29 16:35:02

Tetris鴻蒙

2023-03-30 09:32:27

2022-11-14 17:01:34

游戲開發畫布功能

2023-05-06 07:23:57

2024-02-28 12:12:20

Pipeline數據機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本黄色免费视频 | 久草新在线 | 成人精品鲁一区一区二区 | 久久专区 | 免费视频一区二区 | 国产精品成人在线播放 | 中文字幕成人在线 | 福利一区在线观看 | 成人欧美一区二区三区黑人孕妇 | 国产精品久久久久久久久久久久久 | 国产精品免费在线 | 一区 | 日韩成人免费视频 | 日韩欧美一区二区三区免费观看 | 精品久久久久久国产 | 国产精品久久久久久妇女 | 国产人久久人人人人爽 | 国产一级毛片精品完整视频版 | 超碰最新在线 | 毛片一区 | 91久久 | 日韩成人| 国产在线中文字幕 | 国产特级毛片 | 欧美伊人影院 | 亚洲h视频 | 亚洲九色 | 91久久国产综合久久 | 日韩成人专区 | 国产男人的天堂 | 精品免费国产视频 | 欧美日韩在线精品 | 特黄毛片视频 | 日韩中文字幕 | 久久亚洲精品国产精品紫薇 | 久热伊人 | 国产在线中文字幕 | 在线免费观看a级片 | 91网站视频在线观看 | 视频一区在线观看 | 国产一区二|