日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一起學(xué)WebGL:動(dòng)態(tài)繪制點(diǎn)

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

北湖網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,北湖網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為北湖上千多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請找那個(gè)售后服務(wù)好的北湖做網(wǎng)站的公司定做!

這是系列文章,如果你是初學(xué)者,你需要看上一篇文章才好理解這節(jié)課的內(nèi)容。

??《一起學(xué) WebGL:繪制一個(gè)點(diǎn)》??

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

這節(jié)課我們會(huì)通過 JavaScript 給著色器動(dòng)態(tài)提供數(shù)據(jù),而不需要重新編譯著色器。

靜態(tài)繪制點(diǎn)

先貼上上篇文章的靜態(tài)寫法。

demo 地址:

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

/**
* wegbl 繪制一個(gè)點(diǎn)
*/

/** @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);
}
`;

/**** 渲染器生成處理 ****/
// 創(chuàng)建頂點(diǎn)渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
// 創(chuàng)建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
// 程序?qū)ο?br>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);
// 繪制點(diǎn)
gl.drawArrays(gl.POINTS, 0, 1);

渲染結(jié)果:

外部傳遞點(diǎn)的位置信息

下面我們希望頂點(diǎn)著色器的點(diǎn)的坐標(biāo)可以通過 JavaScript 動(dòng)態(tài)地修改。

加入 attribute 變量

修改頂點(diǎn)著色器的代碼:

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

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

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

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

外部修改 attribute

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

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

第一行 gl.getAttribLocation 方法的作用,是從 gl.program 程序?qū)ο笾?,取出一個(gè)名為 "a_Position" 的 attribute 變量的地址。如果找到,會(huì)返回一個(gè)大于等于 0 的值,找不到會(huì)返回  -1。

第二行,gl.vertexAttrib3f 就是根據(jù)地址給 a_Position 變量賦予值。a_Position 是 4 個(gè)浮點(diǎn)數(shù)組成的矢量類型,我們這里并沒有傳 4 個(gè)值,只傳了 3 個(gè)。最后一個(gè)值對坐標(biāo)系來說并無意義,但在矩陣變換時(shí)會(huì)用到,不提供會(huì)被自動(dòng)填充為默認(rèn)的 1.0。

你也可以用 gl.vertexAttrib4f 提供完成的 4 個(gè)浮點(diǎn)數(shù),或者用 gl.vertexAttrib1f 或 gl.vertexAttrib2f 提供第一個(gè)或前兩個(gè)浮點(diǎn)數(shù)。缺少的 y、z 默認(rèn)會(huì)用 0.0,z 則使用 1.0。

這里我們給 y 設(shè)置了 0.5,渲染結(jié)果為:

關(guān)于坐標(biāo)系的文章

《??一起學(xué) WebGL:坐標(biāo)系??》

補(bǔ)充一下 WebGL 的坐標(biāo)系圖示:

完整代碼:

/**
* wegbl 繪制一個(gè)點(diǎn)
*/

/** @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);
}
`;

/**** 渲染器生成處理 ****/
// 創(chuàng)建頂點(diǎn)渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
// 創(chuàng)建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
// 程序?qū)ο?br>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);
// 繪制點(diǎn)
gl.drawArrays(gl.POINTS, 0, 1);

demo 地址:

不斷修改位置信息

下面我們用一個(gè)定時(shí)器,不斷地修改點(diǎn)的位置。

代碼實(shí)現(xiàn):

/**
* webgl 動(dòng)態(tài)繪制點(diǎn) + 定時(shí)器
*/

/** @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);
}
`;

/**** 渲染器生成處理 ****/
// 創(chuàng)建頂點(diǎn)渲染器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
// 創(chuàng)建片元渲染器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
// 程序?qū)ο?br>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);
// 繪制點(diǎn)
gl.drawArrays(gl.POINTS, 0, 1);
}, 180);

在定時(shí)器中,我們不斷地修用 gl.vertexAttrib3f 修改點(diǎn)的位置,并重繪畫布。

demo 地址:

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

渲染效果:

結(jié)尾

我是前端西瓜哥,歡迎關(guān)注我,學(xué)習(xí)更多前端知識(shí)。

這里布置一個(gè)小練習(xí):動(dòng)態(tài)修改點(diǎn)的大小,這次要用 float 類型,并對應(yīng)使用 g1.vertexAttriblf 傳遞值。

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

下一節(jié)我們將學(xué)習(xí)如何動(dòng)態(tài)修改片元著色器中點(diǎn)的顏色。


名稱欄目:一起學(xué)WebGL:動(dòng)態(tài)繪制點(diǎn)
標(biāo)題URL:http://www.5511xx.com/article/copjddj.html