webgl 基本圖形和基本變換

webgl的 drawArrays函數(shù)及其強(qiáng)大而且靈活,第一個(gè)參數(shù)不同的值,我們就能以7種不同的方式繪制圖形.webgl可以繪制的基本圖形如下所示


image.png

注意

  • 三角帶點(diǎn)擊規(guī)律是:第偶數(shù)個(gè)三角形:以上一個(gè)三角形的第二條邊+下一個(gè)點(diǎn)為基礎(chǔ)亏掀,以和第二條邊相反的方向繪制三角形
    第奇數(shù)個(gè)三角形:以上一個(gè)三角形的第三條邊+下一個(gè)點(diǎn)為基礎(chǔ)派昧,以和第二條邊相反的方向繪制三角形
  • 三角扇的繪制規(guī)律是:已三角形的第三條邊的反方向?yàn)槠瘘c(diǎn)
圖形的移動(dòng) 旋轉(zhuǎn)

圖形嘗試移動(dòng),旋轉(zhuǎn),縮放三角,然后在屏幕上面顯示出來叫做變換或者也叫仿射變換

平移

為了平移一個(gè)三角形需要對(duì)頂點(diǎn)的每個(gè)分量,加上三角形在對(duì)應(yīng)x,y 上平移的距離.在 webgl 中我們只需要對(duì)著色器中的頂點(diǎn)上的每個(gè)分量加上一個(gè)常量就可以實(shí)現(xiàn)平移操作.圖形的平移是逐頂點(diǎn)操作,而不是逐片元操作.
示例代碼如下:

<!DOCTYPE html>
<html>
   <head>
       <meta charset="utf-8">
       <title></title>
   </head>
   <body onload="main()">
       <canvas id="webgl" width="400" height="400"></canvas>
   </body>
   <script id="vertextShader" type="x-shader/x-vertex">
       attribute vec4 a_Position;
       uniform vec4 u_Trabslation;
       void main () {
           gl_Position =u_Trabslation+a_Position;
           // gl_PointSize = 20.0;
       }
   </script>
   <script id="fragmentShader" type="x-shader/x-fragment">
       //  全局設(shè)置浮點(diǎn)數(shù)的精確度,其他類型都有默認(rèn)的精度類型,浮點(diǎn)數(shù)需要單獨(dú)的設(shè)置
       // precision mediump float;
       // uniform vec4 u_FragColor;
       void main () {
           gl_FragColor = vec4(1.0,0.0,0.0,1.0);
       }
   </script>
   <script src="./jsm/util.js"></script>
   <script>
       let tx=0.0,ty=0.0,tz=0.0
       function main () {
           const canvas = document.getElementById('webgl')
           const gl = canvas.getContext('webgl')
           const vertextShader  = document.getElementById('vertextShader').innerText
           const fragmentShader = document.getElementById('fragmentShader').innerText
           if (!initShaders(gl,vertextShader,fragmentShader)) return
           if (!gl) return
           const a_Position = gl.getAttribLocation(gl.program,'a_Position')
           const u_Trabslation = gl.getUniformLocation(gl.program,'u_Trabslation')
           if (a_Position < 0 && u_Trabslation<0) return
           gl.uniform4f(u_Trabslation,tx,ty,tz,0.0)
           const vertexs = [0.0,0.0,0.2,0.0,0.0,0.2]
           //  創(chuàng)建緩沖區(qū)域
           const buffer = gl.createBuffer()
           //  綁定緩沖區(qū)域
           gl.bindBuffer(gl.ARRAY_BUFFER,buffer)
           //  向緩沖區(qū)域?qū)懭霐?shù)據(jù)
           gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertexs),gl.STATIC_DRAW)
           //  將緩沖對(duì)象分配給 attribute 對(duì)象
           gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0)
           // 開啟鏈接 attribute 變量
           gl.enableVertexAttribArray(a_Position)
           gl.clearColor(0.0,0.0,0.0,1.0)
           render(gl)
           canvas.onmousedown = function (e) {
               click(gl,u_Trabslation)
           }
       }
       function render (gl) {
           // 顏色深度清空
           gl.clear(gl.COLOR_BUFFER_BIT) 
           //  開始繪制
           gl.drawArrays(gl.TRIANGLES,0,3)
       }
       function click(gl,u_Trabslation) {
           tx+=0.1
           ty+=0.1
           tz+=0.1
           gl.uniform4f(u_Trabslation,tx,ty,tz,0.0)
           render(gl)
       } 
   </script>
</html>

旋轉(zhuǎn)

旋轉(zhuǎn)比平移稍微復(fù)雜一點(diǎn),對(duì)于旋轉(zhuǎn)來說必須指明:

  • 旋轉(zhuǎn)軸(圖形將圍繞旋轉(zhuǎn)軸旋轉(zhuǎn))
  • 旋轉(zhuǎn)方向(方向:順時(shí)間或者逆時(shí)針)
  • 旋轉(zhuǎn)角度(圖形旋轉(zhuǎn)經(jīng)過的角度)
    例如從 p 點(diǎn)(x,y)旋轉(zhuǎn)到 z點(diǎn)(x1,y1),旋轉(zhuǎn)的角度?,
    X1 = xcos?-ysin?
    Y1 = xsin?+ycos?
    可以把 cos和 sin 值傳遞給頂端著色器,然后在頂點(diǎn)著色器根據(jù)等式計(jì)算出 x1,y1.
    示例代碼如下
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body onload="main()">
        <canvas id="webgl" width="400" height="400"></canvas>
    </body>
    <script id="vertextShader" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        uniform float u_Cosb;
        uniform float u_Sinb;
        void main () {
            // gl_Position = a_Position;
            gl_Position.x = a_Position.x*u_Cosb-a_Position.y*u_Sinb;
            gl_Position.y = a_Position.x*u_Sinb+a_Position.y*u_Cosb;
            gl_Position.z = a_Position.z;
            gl_Position.w =1.0;
        }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
        //  全局設(shè)置浮點(diǎn)數(shù)的精確度,其他類型都有默認(rèn)的精度類型,浮點(diǎn)數(shù)需要單獨(dú)的設(shè)置
        // precision mediump float;
        // uniform vec4 u_FragColor;
        void main () {
            gl_FragColor = vec4(1.0,0.0,0.0,1.0);
        }
    </script>
    <script src="./jsm/util.js"></script>
    <script>
        let tx=0.0,ty=0.0,tz=0.0
        let angle = 0.0;
        function main () {
            const canvas = document.getElementById('webgl')
            const gl = canvas.getContext('webgl')
            const vertextShader  = document.getElementById('vertextShader').innerText
            const fragmentShader = document.getElementById('fragmentShader').innerText
            if (!initShaders(gl,vertextShader,fragmentShader)) return
            if (!gl) return
            const a_Position = gl.getAttribLocation(gl.program,'a_Position')
            const u_Cosb = gl.getUniformLocation(gl.program,'u_Cosb')
            const u_Sinb = gl.getUniformLocation(gl.program,'u_Sinb')
            if (a_Position < 0 ) return
            angleChange(gl,u_Cosb,u_Sinb)
            const vertexs = [0.0,0.0,0.2,0.0,0.0,0.2]
            //  創(chuàng)建緩沖區(qū)域
            const buffer = gl.createBuffer()
            //  綁定緩沖區(qū)域
            gl.bindBuffer(gl.ARRAY_BUFFER,buffer)
            //  向緩沖區(qū)域?qū)懭霐?shù)據(jù)
            gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertexs),gl.STATIC_DRAW)
            //  將緩沖對(duì)象分配給 attribute 對(duì)象
            gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0)
            // 開啟鏈接 attribute 變量
            gl.enableVertexAttribArray(a_Position)
            gl.clearColor(0.0,0.0,0.0,1.0)
            render(gl)
            canvas.onmousedown = function (e) {
                click(gl,u_Cosb,u_Sinb)
            }
        }
        function render (gl) {
            // 顏色深度清空
            gl.clear(gl.COLOR_BUFFER_BIT) 
            //  開始繪制
            gl.drawArrays(gl.TRIANGLES,0,3)
        }
        function angleChange(gl,u_Cosb,u_Sinb) {
            const radian = Math.PI*angle/180.0
            const cosB  = Math.cos(radian)
            const sinB = Math.sin(radian)
            // 產(chǎn)地給頂點(diǎn)著色器
            gl.uniform1f(u_Cosb,cosB)
            gl.uniform1f(u_Sinb,sinB)
        }
        function click(gl,u_Cosb,u_Sinb) {
            angle+=10
            angleChange(gl,u_Cosb,u_Sinb)
            render(gl)
        } 
    </script>
</html>

變換矩陣
對(duì)于簡(jiǎn)單的變換,可以使用數(shù)學(xué)的表達(dá)式計(jì)算,但是當(dāng)情形比較復(fù)雜的時(shí)候,數(shù)學(xué)表達(dá)式就比較繁瑣了.這時(shí)候我們使用數(shù)學(xué)工具-變換矩陣來完成這項(xiàng)工作.在 webgl 中矩陣屬于列主序的.使用 uniformMatrix4fv 函數(shù)想生成的類型數(shù)組穿度個(gè) uniform 變量

gl.unoformMatrix4fv(location,transpose,array)

  • location:uniform 變量的地址
  • transpose:webgl必須為 false
  • array:類型化數(shù)組
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末次企,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒋川,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跟啤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)唉锌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門隅肥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人袄简,你說我怎么就攤上這事腥放。” “怎么了绿语?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵捉片,是天一觀的道長(zhǎng)平痰。 經(jīng)常有香客問我,道長(zhǎng)伍纫,這世上最難降的妖魔是什么宗雇? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮莹规,結(jié)果婚禮上赔蒲,老公的妹妹穿的比我還像新娘。我一直安慰自己良漱,他們只是感情好舞虱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著母市,像睡著了一般矾兜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上患久,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天椅寺,我揣著相機(jī)與錄音,去河邊找鬼蒋失。 笑死返帕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的篙挽。 我是一名探鬼主播荆萤,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铣卡!你這毒婦竟也來了链韭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤煮落,失蹤者是張志新(化名)和其女友劉穎梧油,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體州邢,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡儡陨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了量淌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骗村。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呀枢,靈堂內(nèi)的尸體忽然破棺而出胚股,到底是詐尸還是另有隱情,我是刑警寧澤裙秋,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布琅拌,位于F島的核電站缨伊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏进宝。R本人自食惡果不足惜刻坊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望党晋。 院中可真熱鬧谭胚,春花似錦、人聲如沸未玻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)扳剿。三九已至旁趟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庇绽,已是汗流浹背锡搜。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敛劝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓纷宇,卻偏偏與公主長(zhǎng)得像夸盟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子像捶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 在以前的文章里上陕,不管是繪制圖形,繪制點(diǎn)亦或者是改變色值拓春,所有的內(nèi)容都是靜態(tài)的释簿。 在 webgl 里,圖形的運(yùn)動(dòng)分為...
    yancy_1012閱讀 484評(píng)論 0 2
  • 1. 前言 圖形的動(dòng)畫是由平移硼莽、旋轉(zhuǎn)庶溶、和縮放三種基礎(chǔ)的變換方式組成。 之前的文章里懂鸵,分享了下如何進(jìn)行圖形的平移偏螺。《...
    yancy_1012閱讀 289評(píng)論 2 1
  • 前言 地圖的渲染其實(shí)可以分解為線匆光、面套像、紋理、文字的渲染终息。為了了解地圖渲染的實(shí)現(xiàn)原理并實(shí)際練習(xí)WebGL夺巩,進(jìn)行了這個(gè)...
    多多洛寫東西閱讀 4,312評(píng)論 1 3
  • 前言 關(guān)于圖形的動(dòng)畫內(nèi)容贞让,之前已經(jīng)分享完成了兩篇,分別是webgl變換:深入圖形平移[https://juejin...
    yancy_1012閱讀 267評(píng)論 0 1
  • 轉(zhuǎn)載請(qǐng)注明出處:【huachao1001的簡(jiǎn)書:http://www.reibang.com/users/0a7e...
    huachao1001閱讀 6,837評(píng)論 10 35