WebGL?繪制與變換使用示例詳解
緩沖區(qū)對(duì)象(buffer object)
其中的API方法的說(shuō)明官方網(wǎng)址:WebGLRenderingContext
緊接上一篇的問(wèn)題,其實(shí)通過(guò)片元著色器可以修改點(diǎn)的顏色,但是會(huì)發(fā)現(xiàn)每一次顏色的都是一樣的,兩種方式的區(qū)別就是第一種用到了緩沖區(qū)對(duì)象
解釋?zhuān)篵uffer object,它可以一次性向著色器中傳入多個(gè)頂點(diǎn)數(shù)據(jù),而緩沖區(qū)對(duì)象是WebGL中一塊內(nèi)存區(qū)域,我們可以一次性向其中傳入大量的頂點(diǎn)數(shù)據(jù)。
再來(lái)看一眼相關(guān)代碼
api說(shuō)明
createBuffer: creates and initializes aWebGLBufferstoring data such as vertices or colors -- 創(chuàng)建和初始化一個(gè)可以存儲(chǔ)類(lèi)似頂點(diǎn)和顏色數(shù)據(jù)的對(duì)象bindBuffer: binds a givenWebGLBufferto a target -- 將buffer對(duì)象綁定到目標(biāo)對(duì)象上bufferData: initializes and creates the buffer object's data store -- 存儲(chǔ)數(shù)據(jù)到創(chuàng)建的buffer對(duì)象中enableVertexAttribArray: turns on the generic vertex attribute array at the specified index into the list of attribute arrays. -- 傳入的參數(shù)是一個(gè)vertex類(lèi)型的數(shù)組對(duì)象,這個(gè)方法可以依次打開(kāi)這個(gè)數(shù)組vertexAttribPointer: binds the buffer currently bound togl.ARRAY_BUFFERto a generic vertex attribute of the current vertex buffer object and specifies its layout. -- 將整個(gè)數(shù)組中的所有值一次性分配給一個(gè)attribute變量
解析:首先創(chuàng)建多個(gè)長(zhǎng)度的數(shù)組,用來(lái)裝著色器中需要修改的頂點(diǎn)或是顏色信息,之后創(chuàng)建一個(gè)buffer,再將webgl對(duì)象和當(dāng)前創(chuàng)建的buffer地址綁定一起,bufferData方法就是往buffer地址中傳入數(shù)組數(shù)據(jù)
繪制圖形
上面的例子中都是繪制一個(gè)點(diǎn),只不過(guò)這個(gè)點(diǎn)的size可以自定義設(shè)置
webgl.drawArrays(webgl.POINTS, 0, points.length / 4)
其中的drawArrays中的第一個(gè)參數(shù)指的是不同的繪制方式
參數(shù)類(lèi)型
gl.POINTS點(diǎn),繪制在坐標(biāo)系內(nèi)gl.LINES線,分別是點(diǎn)1和點(diǎn)2的線,點(diǎn)3和點(diǎn)4的線...gl.LINE_STRIP線,連接點(diǎn)1-點(diǎn)2-點(diǎn)3...gl.LINE_LOOP線,連接點(diǎn)1-點(diǎn)2-點(diǎn)3-點(diǎn)1,點(diǎn)的首尾相連gl.TRIANGLES三角形, 繪制在(點(diǎn)1,點(diǎn)2,點(diǎn)3)...gl.TRIANGLE_STRIP三角帶,第二個(gè)三角形和第一個(gè)三角形共享一條邊gl.gl.TRIANGLE_FAN三角扇

移動(dòng)、旋轉(zhuǎn)、縮放
const VSHADER_SOURCE = `
attribute vec4 a_Position;
uniform vec4 u_Translate;
void main() {
gl_Position = u_Translate + a_Position;
}
`
const u_Translate = gl.getUniformLocation(gl.program, 'u_Translate')
gl.uniform4f(u_Translate, 0.5, 0.5, 0.0, 0)
創(chuàng)建初始的坐標(biāo)點(diǎn)
const u_Translate = gl.getUniformLocation(program, 'u_Translate'); // 定義頂點(diǎn)數(shù)據(jù) const positions = [ 0, 0, 0.5, 0, 0.5, 0.5, 0, 0.5, ]; // 將頂點(diǎn)數(shù)據(jù)寫(xiě)入緩沖區(qū) gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); // 啟用屬性并指定數(shù)據(jù)格式 gl.enableVertexAttribArray(aPosition); gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0); // 設(shè)置平移向量 const translation = [0.5, 0.5]; // 將平移向量傳遞給uniform變量 gl.uniform2fv(translationUniformLocation, translation); // 繪制圖形 gl.drawArrays(gl.TRIANGLE_FAN, 0, positions.length / 2);
u_Translate + a_Position為每一個(gè)分量相加得到一個(gè)新的vec4值。
自動(dòng)旋轉(zhuǎn)

定義頂點(diǎn)著色器:一個(gè)頂點(diǎn)的信息,然后可以設(shè)置旋轉(zhuǎn)中心點(diǎn)的錨點(diǎn),旋轉(zhuǎn)的角度,和一個(gè)需要改變的顏色
const vertexShaderSource = `
attribute vec2 a_position;
uniform vec2 u_rotationCenter;
uniform float u_angle;
varying vec3 v_color;
void main() {
vec2 rotatedPosition = vec2(
cos(u_angle) * (a_position.x - u_rotationCenter.x) - sin(u_angle) * (a_position.y - u_rotationCenter.y) + u_rotationCenter.x,
sin(u_angle) * (a_position.x - u_rotationCenter.x) + cos(u_angle) * (a_position.y - u_rotationCenter.y) + u_rotationCenter.y
);
gl_Position = vec4(rotatedPosition, 0, 1);
v_color = vec3(cos(u_angle), 3.14 - cos(u_angle), cos(u_angle));
}
`
這樣在片元著色器中就需要
const fragmentShaderSource = `
precision mediump float;
varying vec3 v_color;
void main() {
gl_FragColor = vec4(v_color, 1);
}
`
v_color屬性是從頂點(diǎn)著色器中綁定而來(lái)的
// 設(shè)置旋轉(zhuǎn)中心和旋轉(zhuǎn)角度
const rotationCenter = [0.25, 0.25];
let angle = 0
function render() {
// 更新旋轉(zhuǎn)角度
angle += 0.01
if (angle === 3.1415926) {
angle = 0
}
// 將旋轉(zhuǎn)中心和旋轉(zhuǎn)角度傳遞給uniform變量
webgl.uniform2fv(rotationCenterUniformLocation, rotationCenter)
webgl.uniform1f(angleUniformLocation, angle)
draw()
// 繪制圖形
webgl.drawArrays(webgl.TRIANGLE_FAN, 0, 4);
// 請(qǐng)求瀏覽器調(diào)用下一幀動(dòng)畫(huà)
requestAnimationFrame(render)
}
// 開(kāi)始動(dòng)畫(huà)
render()
縮放
demo實(shí)現(xiàn):根據(jù)滑動(dòng)鼠標(biāo)控制三角形中的縮放大小

代碼實(shí)現(xiàn)
var vertexShaderSource = `
attribute vec3 aVertexPosition;
uniform float uScale;
void main() {
gl_Position = vec4(aVertexPosition * uScale, 1.0);
}
`
頂點(diǎn)著色器中定義了uniform的變量uScale,比例因子,通過(guò)之后的代碼中
const scaleUniformLocation = webgl.getUniformLocation(webgl.program, "uScale") webgl.uniform1f(scaleUniformLocation, scale)
重新設(shè)置該變量的值 監(jiān)聽(tīng)鼠標(biāo)滑動(dòng)事件
canvas.addEventListener("wheel", function (event: any) {
scale += event.deltaY / 1000
})
補(bǔ)充說(shuō)明
變換中主要用到是矩陣的知識(shí),矩陣按儲(chǔ)存方式分為按行矩陣和按列矩陣,而WebGL中主要是按列矩陣

那么使用矩陣可以 <新坐標(biāo)> = <變換矩陣> * <舊坐標(biāo)>
以上就是WebGL 繪制與變換使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于WebGL繪制變換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
鼠標(biāo)經(jīng)過(guò)tr時(shí),改變tr當(dāng)前背景顏色
本篇文章主要介紹了鼠標(biāo)經(jīng)過(guò)tr時(shí),改變tr當(dāng)前背景顏色的示例代碼,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
JavaScript實(shí)現(xiàn)導(dǎo)入導(dǎo)出excel的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript語(yǔ)言實(shí)現(xiàn)導(dǎo)入導(dǎo)出excel文件的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-07-07
微信小程序判斷手機(jī)號(hào)是否合法的實(shí)例代碼
我們?cè)谖⑿判〕绦蜷_(kāi)發(fā)的時(shí)候,手機(jī)號(hào)的驗(yàn)證是經(jīng)常需要操作的,那么如何驗(yàn)證手機(jī)號(hào)呢?這篇文章主要給大家介紹了關(guān)于微信小程序判斷手機(jī)號(hào)是否合法的相關(guān)資料,需要的朋友可以參考下2021-09-09
JS實(shí)現(xiàn)表單全選以及取消全選實(shí)例
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)表單全選以及取消全選實(shí)例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Three.js利用orbit controls插件(軌道控制)控制模型交互動(dòng)作詳解
這篇文章主要給大家介紹了關(guān)于Three.js利用orbit controls插件,也就是軌道控制來(lái)控制模型交互動(dòng)作的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-09-09
簡(jiǎn)單了解JavaScript中常見(jiàn)的反模式
這篇文章主要介紹了簡(jiǎn)單了解JavaScript中常見(jiàn)的反模式,反模式 是指對(duì)反復(fù)出現(xiàn)的設(shè)計(jì)問(wèn)題的常見(jiàn)的無(wú)力而低效的設(shè)計(jì)模式,俗話說(shuō)就是重蹈覆轍。 這篇文章描述了 JavaScript 中常見(jiàn)的一些反模式,以及避免它們的辦法。,需要的朋友可以參考下2019-06-06
JavaScript實(shí)現(xiàn)仿新浪微博大廳和騰訊微博首頁(yè)滾動(dòng)特效源碼
最近看到朋友用JavaScript實(shí)現(xiàn)仿新浪微博大廳和未登錄騰訊微博首頁(yè)滾動(dòng)效果,朋友使用jquery實(shí)現(xiàn)的,在網(wǎng)上看到有用js制作的也比較好,于是把我的內(nèi)容整理分享給大家,具體詳解請(qǐng)看本文2015-09-09

