<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WebGL簡易教程(六):第一個三維示例(使用模型視圖投影變換)

      1. 概述

      在上一篇教程《WebGL簡易教程(五):圖形變換(模型、視圖、投影變換)》中,詳細(xì)講解了OpenGL\WebGL關(guān)于繪制場景的模型變換、視圖變換以及投影變換的過程。不過那篇教程是純理論知識,這里就具體結(jié)合一個實際的例子,進(jìn)一步理解WebGL中是如何通過圖形變換讓一個真正的三維場景顯示出來。

      2. 示例:繪制多個三角形

      繼續(xù)改進(jìn)之前的代碼,這次就更進(jìn)一步,在一個場景中繪制了三個三角形。

      2.1. Triangle_MVPMatrix.html

      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8" />
          <title>Hello Triangle</title>
        </head>
      
        <body onload="main()">
          <canvas id="webgl" width="400" height="400">
          Please use a browser that supports "canvas"
          </canvas>
      
          <script src="../lib/webgl-utils.js"></script>
          <script src="../lib/webgl-debug.js"></script>
          <script src="../lib/cuon-utils.js"></script>
          <script src="../lib/cuon-matrix.js"></script>
          <script src="Triangle_MVPMatrix.js"></script>
        </body>
      </html>
      

      與之間的代碼相比,這段代碼主要是引入了一個cuon-matrix.js,這個是一個圖形矩陣的處理庫,能夠方便與GLSL進(jìn)行交互。

      2.2. Triangle_MVPMatrix.js

      // 頂點著色器程序
      var VSHADER_SOURCE =
        'attribute vec4 a_Position;\n' + // attribute variable
        'attribute vec4 a_Color;\n' +
        'uniform mat4 u_MvpMatrix;\n' +
        'varying vec4 v_Color;\n' +
        'void main() {\n' +
        '  gl_Position = u_MvpMatrix * a_Position;\n' + // Set the vertex coordinates of the point
        '  v_Color = a_Color;\n' +
        '}\n';
      
      // 片元著色器程序
      var FSHADER_SOURCE =
        'precision mediump float;\n' +
        'varying vec4 v_Color;\n' +
        'void main() {\n' +
        '  gl_FragColor = v_Color;\n' +
        '}\n';
      
      function main() {
        // 獲取 <canvas> 元素
        var canvas = document.getElementById('webgl');
      
        // 獲取WebGL渲染上下文
        var gl = getWebGLContext(canvas);
        if (!gl) {
          console.log('Failed to get the rendering context for WebGL');
          return;
        }
      
        // 初始化著色器
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
          console.log('Failed to intialize shaders.');
          return;
        }
      
        // 設(shè)置頂點位置
        var n = initVertexBuffers(gl);
        if (n < 0) {
          console.log('Failed to set the positions of the vertices');
          return;
        }
      
        //設(shè)置MVP矩陣
        setMVPMatrix(gl,canvas);
      
        // 指定清空<canvas>的顏色
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
      
        // 開啟深度測試
        gl.enable(gl.DEPTH_TEST);
      
        // 清空顏色和深度緩沖區(qū)
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
      
        // 繪制三角形
        gl.drawArrays(gl.TRIANGLES, 0, n);
      }
      
      //設(shè)置MVP矩陣
      function setMVPMatrix(gl,canvas) {
        // Get the storage location of u_MvpMatrix
        var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
        if (!u_MvpMatrix) {
          console.log('Failed to get the storage location of u_MvpMatrix');
          return;
        }
      
        //模型矩陣
        var modelMatrix = new Matrix4();
        modelMatrix.setTranslate(0.75, 0, 0);
      
        //視圖矩陣
        var viewMatrix = new Matrix4();  // View matrix
        viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
      
        //投影矩陣
        var projMatrix = new Matrix4();  // Projection matrix
        projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100);
      
        //MVP矩陣
        var mvpMatrix = new Matrix4();
        mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);
      
        //將MVP矩陣傳輸?shù)街鞯膗niform變量u_MvpMatrix
        gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
      }
      
      //
      function initVertexBuffers(gl) {
        // 頂點坐標(biāo)和顏色
        var verticesColors = new Float32Array([
          0.0, 1.0, -4.0, 0.4, 1.0, 0.4,  //綠色在后
          -0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
          0.5, -1.0, -4.0, 1.0, 0.4, 0.4,
      
          0.0, 1.0, -2.0, 1.0, 1.0, 0.4, //黃色在中
          -0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
          0.5, -1.0, -2.0, 1.0, 0.4, 0.4,
      
          0.0, 1.0, 0.0, 0.4, 0.4, 1.0,  //藍(lán)色在前
          -0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
          0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
        ]);
      
        //
        var n = 9; // 點的個數(shù)
        var FSIZE = verticesColors.BYTES_PER_ELEMENT;   //數(shù)組中每個元素的字節(jié)數(shù)
      
        // 創(chuàng)建緩沖區(qū)對象
        var vertexBuffer = gl.createBuffer();
        if (!vertexBuffer) {
          console.log('Failed to create the buffer object');
          return -1;
        }
      
        // 將緩沖區(qū)對象綁定到目標(biāo)
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        // 向緩沖區(qū)對象寫入數(shù)據(jù)
        gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
      
        //獲取著色器中attribute變量a_Position的地址 
        var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
        if (a_Position < 0) {
          console.log('Failed to get the storage location of a_Position');
          return -1;
        }
        // 將緩沖區(qū)對象分配給a_Position變量
        gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
      
        // 連接a_Position變量與分配給它的緩沖區(qū)對象
        gl.enableVertexAttribArray(a_Position);
      
        //獲取著色器中attribute變量a_Color的地址 
        var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
        if (a_Color < 0) {
          console.log('Failed to get the storage location of a_Color');
          return -1;
        }
        // 將緩沖區(qū)對象分配給a_Color變量
        gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
        // 連接a_Color變量與分配給它的緩沖區(qū)對象
        gl.enableVertexAttribArray(a_Color);
      
        // 解除綁定
        gl.bindBuffer(gl.ARRAY_BUFFER, null);
      
        return n;
      }
      

      相比之前的代碼,主要做了3點改進(jìn):

      1. 數(shù)據(jù)加入Z值;
      2. 加入了深度測試;
      3. MVP矩陣設(shè)置;

      2.2.1. 數(shù)據(jù)加入Z值

      之前繪制的三角形,只有X坐標(biāo)和Y坐標(biāo),Z值坐標(biāo)自動補足為默認(rèn)為0的。在這里會繪制了3個三角形,每個三角形的深度不同。如下代碼所示,定義了3個三角形9個點,每個點包含xyz信息和rgb信息:

        // 頂點坐標(biāo)和顏色
        var verticesColors = new Float32Array([
          0.0, 1.0, -4.0, 0.4, 1.0, 0.4,  //綠色在后
          -0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
          0.5, -1.0, -4.0, 1.0, 0.4, 0.4,
      
          0.0, 1.0, -2.0, 1.0, 1.0, 0.4, //黃色在中
          -0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
          0.5, -1.0, -2.0, 1.0, 0.4, 0.4,
      
          0.0, 1.0, 0.0, 0.4, 0.4, 1.0,  //藍(lán)色在前
          -0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
          0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
        ]);
      

      這意味著與著色器傳輸變量的函數(shù)gl.vertexAttribPointer()的參數(shù)也得相應(yīng)的變化。注意要深入理解這個函數(shù)每個參數(shù)代表的含義:

        // ...
      
        // 將緩沖區(qū)對象分配給a_Position變量
        gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
      
        // ...
        // 將緩沖區(qū)對象分配給a_Color變量
        gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
      

      2.2.2. 加入深度測試

      在默認(rèn)情況下,WebGL是根據(jù)頂點在緩沖區(qū)的順序來進(jìn)行繪制的,后繪制的圖形會覆蓋已經(jīng)繪制好的圖形。但是這樣往往與實際物體遮擋情況不同,造成一些很怪異的現(xiàn)象,比如遠(yuǎn)的物體反而遮擋了近的物體。所以WebGL提供了一種深度檢測(DEPTH_TEST)的功能,啟用該功能就會檢測物體(實際是每個像素)的深度,來決定是否繪制。其啟用函數(shù)為:
      2
      除此之外,還應(yīng)該注意在繪制每一幀之前都應(yīng)該清除深度緩沖區(qū)(depth buffer)。WebGL有多種緩沖區(qū)。我們之前用到的與頂點著色器交互的緩沖區(qū)對象就是頂點緩沖區(qū),每次重新繪制刷新的就是顏色緩沖區(qū)。深度緩沖區(qū)記錄的就是每個幾何圖形的深度信息,每繪制一幀,都應(yīng)清除深度緩沖區(qū):
      3
      在本例中的相關(guān)代碼為:

        // ...
      
        // 開啟深度測試
        gl.enable(gl.DEPTH_TEST);
      
        // 清空顏色和深度緩沖區(qū)
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
      
        // ...
      

      2.2.3. MVP矩陣設(shè)置

      在上一篇教程中提到過,WebGL的任何圖形變換過程影響的都是物體的頂點,模型變換、視圖變換、投影變換都是在頂點著色器中實現(xiàn)的。由于每個頂點都是要進(jìn)行模型視圖投影變換的,所以可以合并成一個MVP矩陣,將其傳入到頂點著色器中的:

        //...
        'uniform mat4 u_MvpMatrix;\n' +  
        'void main() {\n' +
        '  gl_Position = u_MvpMatrix * a_Position;\n' + // Set the vertex coordinates of the point 
        //...
        '}\n';
      

      在函數(shù)setMVPMatrix()中,創(chuàng)建了MVP矩陣,并將其傳入到著色器:

      //設(shè)置MVP矩陣
      function setMVPMatrix(gl,canvas) {
        // Get the storage location of u_MvpMatrix
        var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
        if (!u_MvpMatrix) {
          console.log('Failed to get the storage location of u_MvpMatrix');
          return;
        }
      
        //模型矩陣
        var modelMatrix = new Matrix4();
        modelMatrix.setTranslate(0.75, 0, 0);
      
        //視圖矩陣
        var viewMatrix = new Matrix4();  // View matrix
        viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
      
        //投影矩陣
        var projMatrix = new Matrix4();  // Projection matrix
        projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100);
      
        //MVP矩陣
        var mvpMatrix = new Matrix4();
        mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);
      
        //將MVP矩陣傳輸?shù)街鞯膗niform變量u_MvpMatrix
        gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
      }
      

      在上述代碼中,依次分別設(shè)置了:

      • 模型矩陣:X方向上平移了0.75個單位。
      • 視圖矩陣:視點為(0,0,5),觀察點為(0,0,-100),上方向為(0,1,0)的觀察視角。
      • 投影矩陣:垂直張角為30,畫圖視圖的寬高比,近截面距離為1,遠(yuǎn)截面為100的視錐體。

      三者級聯(lián),得到MVP矩陣,將其傳入到頂點著色器中。

      3. 結(jié)果

      用瀏覽器打開Triangle_MVPMatrix.html,就會發(fā)現(xiàn)瀏覽器頁面顯示了一個由遠(yuǎn)及近,近大遠(yuǎn)小的三個三角形。如圖所示:
      1

      4. 參考

      本來部分代碼和插圖來自《WebGL編程指南》。

      代碼和數(shù)據(jù)地址

      上一篇
      目錄
      下一篇

      posted @ 2019-10-05 21:41  charlee44  閱讀(2487)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品人妻中文字幕有码在线 | 日韩激情一区二区三区| 国产成人亚洲无码淙合青草| 国产免费久久精品44| 色综合色综合色综合频道| 久久亚洲国产成人亚| 亚洲成A人片在线观看无码不卡| 国产在线线精品宅男网址| 一区二区三区AV波多野结衣| 亚洲中文字幕成人综合网| 国产成人亚洲欧美二区综合| 四虎亚洲国产成人久久精品 | 久久精品国产精品亚洲| 久久人与动人物a级毛片| 国产激情无码一区二区三区| 亚洲国产一区二区三区亚瑟| 新巴尔虎右旗| 高中女无套中出17p| 亚洲AV蜜桃永久无码精品| 丁香五月网久久综合| 国产成人精品无人区一区| 秋霞人妻无码中文字幕| 遂平县| 亚洲老妇女一区二区三区| 国产精品SM捆绑调教视频| 国内精品视频一区二区三区| 中文字幕色偷偷人妻久久| 国产一区二区午夜福利久久| 天堂va欧美ⅴa亚洲va在线| 游戏| 99riav国产精品视频| 国产精品嫩草99av在线| 国产精品制服丝袜无码| 人人爽人人爽人人片a免费| 92成人午夜福利一区二区| 91精品亚洲一区二区三区| 国内不卡一区二区三区| 午夜性爽视频男人的天堂| 亚洲精品一区二区二三区| 国产精品福利自产拍在线观看 | 99久久婷婷国产综合精品青草漫画|