《WebGL编程指南》读书笔记之绘制和变换三角形

构建三维模型的基本单位是三角形。通过创建细小、大量的三角形,可以创建复杂、逼真的三维模型。

  • 绘制多个点

    • 缓冲区对象:可以一次性地向着色器传入多个顶点的数据

    • 设置点的坐标信息

      步骤:

      1. 创建缓冲区对象
      2. 绑定缓冲区对象
      3. 将数据写入缓冲区对象
      4. 将缓冲区对象分配给一个attribute变量
      5. 开启attribute变量

      关键代码:

      function initVertexBuffers(gl) {
        var vertices = new Float32Array([
          0.0, 0.5,   -0.5, -0.5,   0.5, -0.5
        ]);
        var n = 3; // 点的个数
      
        // 创建缓冲区对象
        // gl.deleteBuffer(buffer)-->删除缓冲区对象
        var vertexBuffer = gl.createBuffer();
        if (!vertexBuffer) {
          console.log('Failed to create the buffer object');
          return -1;
        }
      
        // 将缓冲区对象绑定到目标
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        // 向缓冲区对象中写入数据
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
      
        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;
        }
        // 将缓冲区对象分配给a_Position变量
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
      
        // 连接a_Position变量与分配给它的缓冲区对象
        gl.enableVertexAttribArray(a_Position);
      
        return n;
      }
      
    • 类型化数组

    • gl.drawArrays()的第2和第3个参数

  • 绘制三角形

    • 关键代码

      var VSHADER_SOURCE =
        'attribute vec4 a_Position;\n' +
        'void main() {\n' +
        '  gl_Position = a_Position;\n' +
        '}\n';// 删除了gl_PointSize = 10.0;
      
      // gl.drawArrays()的第一个参数变化了
      gl.drawArrays(gl.TRIANGLES, 0, n);
      
  • 绘制矩形

    • 关键代码

      // 设置四个顶点
      var vertices = new Float32Array([
          -0.5, 0.5,   -0.5, -0.5,   0.5, 0.5, 0.5, -0.5
        ]);
      
      // 定义顶点个数
      var n = 4;
      
      // 绘制矩形
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
      
  • 变换(仿射变换)

    • 平移

      逐顶点操作:为顶点坐标的每个分量加上一个常量

      关键代码

      // 将平移距离的值传人顶点着色器,然后分别加在顶点坐标的对应分量上,再赋值给gl_Position
      
      var VSHADER_SOURCE =
        'attribute vec4 a_Position;\n' +
        'uniform vec4 u_Translation;\n' +
        'void main() {\n' +
        '  gl_Position = a_Position + u_Translation;\n' +
        '}\n';
      
      var Tx = 0.5, Ty = 0.5, Tz = 0.0;
      
      var u_Translation = gl.getUniformLocation(gl.program, 'u_Translation');
      
      gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
      
    • 旋转

      • 旋转轴
      • 旋转方向
      • 旋转角度

      关键代码:

      var VSHADER_SOURCE =
        // x' = x cosβ - y sinβ
        // y' = x sinβ + y cosβ 
        // z' = z
        'attribute vec4 a_Position;\n' +
        'uniform float u_CosB, u_SinB;\n' +
        'void main() {\n' +
        '  gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' +
        '  gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n' +
        '  gl_Position.z = a_Position.z;\n' +
        '  gl_Position.w = 1.0;\n' +
        '}\n';
      
      var ANGLE = 90.0; 
      
      var radian = Math.PI * ANGLE / 180.0; // 转换为弧度制
      var cosB = Math.cos(radian);
      var sinB = Math.sin(radian);
      
      var u_CosB = gl.getUniformLocation(gl.program, 'u_CosB');
      var u_SinB = gl.getUniformLocation(gl.program, 'u_SinB');
      if (!u_CosB || !u_SinB) {
        console.log('Failed to get the storage location of u_CosB or u_SinB');
        return;
      }
      gl.uniform1f(u_CosB, cosB);
      gl.uniform1f(u_SinB, sinB);
      
    • 变换矩阵

      • 旋转矩阵:

        • 原理

        • 公式

        • 关键代码

          var VSHADER_SOURCE =
            'attribute vec4 a_Position;\n' +
            'uniform mat4 u_xformMatrix;\n' +
            'void main() {\n' +
            '  gl_Position = u_xformMatrix * a_Position;\n' +
            '}\n';
          
          //创建旋转矩阵
          var radian = Math.PI * ANGLE / 180.0; 
          var cosB = Math.cos(radian), sinB = Math.sin(radian);
          
            // 注意WebGL中矩阵是列主序的
          var xformMatrix = new Float32Array([
              cosB, sinB, 0.0, 0.0,
              -sinB, cosB, 0.0, 0.0,
              0.0,  0.0, 1.0, 0.0,
              0.0,  0.0, 0.0, 1.0
          ]);
          
          // 将旋转矩阵传输给顶点着色器
          var u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix');
          
          gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
          
  • 平移矩阵:

    • 原理
    • 公式
    • 关键代码:
    var xformMatrix = new Float32Array([
        1.0, 0.0, 0.0, 0.0,
        0.0, 1.0, 0.0, 0.0,
        0.0,  0.0, 1.0, 0.0,
        Tx,  Ty, Tz, 1.0
    ]);
    
  • 缩放矩阵:

    • 原理

    • 公式

    • 关键代码

      var Sx = 1.0,Sy = 1.5,Sz = 1.0
      
      var xformMatrix = new Float32Array([
          Sx, 0.0, 0.0, 0.0,
          0.0, Sy, 0.0, 0.0,
          0.0,  0.0, Sz, 0.0,
          0.0,  0.0, 0.0, 1.0
      ]);
      
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容