阅读 467

webgl笔记(webgl编程指南pdf)

webgl

  • webgl 需要用到 canvas

  • MDN 链接

canvas

  • 画布

  • 使用方法,新建 canvas 标签

  • js 获取,然后使用 getContext 获取上下文

  • 使用上下文对象上的 api 来进行绘制

getContext

  • 详情

  • 获取上下文

  • 两个参数(contextType,contextAttributes)

  • contextType 是 string 类型

    • '2d'创建 2d 上下文对象

    • 'webgl'创建 webgl 上下文对象(三维)

    • 'bitmaprenderer'创建放置图片的上下文

  • contextAttributes 是可选参数,为 object 类型

  • 返回值:正常情况返回上下文对象,失败返回null

  • 特点:标签内部书写的内容,是在浏览器不兼容 canvas 的时候才显示

  • 坐标系:canvas 坐标系原点在左上角

  • 同一个作用域中只能有一个类型的上下文,否则会报错

let canvas = document.querySelector("#canvas"); let ctx = canvas.getContext("2d"); 复制代码

2d 上下文

常用属性
  • fillStyle 设置颜色,

    • 值是 string,设置后存储在缓存区

常用方法
  • fillRect 设置矩形,颜色是最近的一个 fillStyle

    • 四个值,距左距离,距上距离,宽,高,类型都是 number

  • drawArrays 绘制图形 ,链接

    • mode 指定绘制的方式,接收常量符号,如下:

    • first

    • count

    • gl.POINTS 绘制一系列点

    • gl.LINES 绘制一系列单独线段。每两个点作为端点,线段之间不连接。

    • gl.LINE_STRIP 绘制一个线条。即,绘制一系列线段,上一点连接下一点。

    • gl.LINE_LOOP 绘制一个线圈。即,绘制一系列线段,上一点连接下一点,并且最后一点与第一个点相连。

    • gl.TRIANGLES 绘制一系列三角形。每三个点作为顶点。

    • gl.TRIANGLE_STRIP 绘制一个三角带

    • gl.TRIANGLE_FAN 绘制一个三角扇

    • 注意:如果 mode 不是这几个值会抛出 gl.INVALID_ENUM 异常。

    • 类型为整数,指定从哪个点开始绘制。

    • 注意:如果这个值为负数会抛出 gl.INVALID_VALUE 异常

    • 整数型,指定绘制需要用到多少个顶点

    • 没有返回值

    • 三个参数(mode, first, count)

gl 上下文(3d)

常用属性

常用方法
  • clearColor 设置清除颜色

    • 四个值:都是 float 类型,rgba

  • clear 清除画布

    • gl.COLOR_BUFFER_BIT 指定深度缓冲区

    • gl.DEPTH_BUFFER_BIT 指定颜色缓存

    • gl.STENCIL_BUFFER_BIT 指定模板缓冲区

    • 一个参数,(gl 是 gl 的上下文,可以使用其他变量)

    • 返回值:无

    • 如果前面没有设置清除颜色,默认为白色

着色器

  • CDN 链接

  • 分为两种,定点着色器和片元着色器

  • 共同点

    • 都要先存储为字符串,然后调用方法使用

    • 字符串内容都要有 main 函数,而且也不要给 main 函数自定义参数,且 main 函数前的 void 表示他不可以有返回值

    • 且内部函数内部需要放置一些规范内容,在下面分析

定点着色器

  • 描述顶点位置的,顶点可以理解为是每个顶端

  • 顶点着色器需要对顶点坐标进行转换,通过gl_Position保存处理过的的顶点(表示顶点位置),类型为vec4,这个变量必须要写

  • gl_PointSize 变量为可选变量,类型为 float,表示点的尺寸(像素为单位),如果不写的话默认为 1.0

片元着色器(片段着色器)

  • 在顶点着色器处理完成后,绘制颜色和纹理

  • 片元就是显示在屏幕上的像素,可以理解为这个片元包含了这个像素的位置,颜色以及其他信息

  • 将点的颜色处理后复制给gl_FragColor变量,也是它控制这个像素在显示器上的最终展示颜色,必须要写,类型为 vec4,也就是 rgba 颜色

vec4 方法
  • 参数有四个,都是浮点型

  • 作用:返回 vec4 对象

  • 注意(总是迷糊):这个方法只是处理了四个参数,而不是只能用于处理坐标,他也可以处理 rgba 颜色

齐次坐标
  • 由 4 个参数组成,(x,y,z,w),等价于三维坐标(x/w,y/w,z/w)

  • 因为齐次坐标是四维的,而他的特点是如果 w 为 1.0 的话,就等价于三维,所以经常用于表示顶点的三维坐标使用(好处:提高准确性)

  • 需要注意:0<= w <=1.0

demo(有些方法暂时没搞懂)
<!DOCTYPE html> <html lang="en">   <head>     <meta charset="UTF-8" />     <meta http-equiv="X-UA-Compatible" content="IE=edge" />     <meta name="viewport" content="width=device-width, initial-scale=1.0" />     <title>Document</title>     <style>       * {         margin: 0;         padding: 0;       }       body {         width: 100vw;         height: 100vh;       }     </style>   </head>   <body>     <canvas id="canvas">不兼容</canvas>   </body> </html> <script src="https://cdn.jsdelivr.net/npm/gl-matrix@3.0.0/gl-matrix-min.js"></script> <script>   // mat4在下面会用到,因为依赖于matrix库,而matrix库更新了,将mat4放在了glMatrix上,所以我们手动将他存在全局   const mat4 = glMatrix.mat4;   const canvas = document.querySelector("#canvas");   canvas.width = document.body.clientWidth;   canvas.height = document.body.clientHeight;   const gl = canvas.getContext("webgl"); </script> <script>   //顶点着色器   const vsSource = `     attribute vec4 aVertexPosition;     uniform mat4 uModelViewMatrix;     uniform mat4 uProjectionMatrix;     void main() {       gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;     }   `;   //片元着色器   //vec方法接受了四个值,可以称之为齐次坐标是四维的,在三维图形系统中被大量使用,如果最后一个值为1.0那么就表示前三个参数为坐标点   const fsSource = `     void main() {       gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);     }   `;   // 创建指定类型的着色器,上传source源码并编译   function loadShader(gl, type, source) {     // 创建一个着色器     const shader = gl.createShader(type);     // 将源码发送到着色器     gl.shaderSource(shader, source);     // 着色器获取到源代码,开始编译     gl.compileShader(shader);     // 调用getShaderParameter,指定着色器shader和要检查的值gl.COMPILE_STATUS,如果返回错误,代表编译失败     if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {       //编译失败,就通过getShaderInfoLog拿到日志,然后输出       alert(         "An error occurred compiling the shaders: " +           gl.getShaderInfoLog(shader)       );       //输出后使用deleteShader删除着色器,然后返回null       gl.deleteShader(shader);       return null;     }     //编译成功,返回编译的着色器     return shader;   }   //  初始化着色器程序,让WebGL知道如何绘制我们的数据   function initShaderProgram(gl, vsSource, fsSource) {     const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);     const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);     // 创建着色器程序     const shaderProgram = gl.createProgram();     gl.attachShader(shaderProgram, vertexShader);     gl.attachShader(shaderProgram, fragmentShader);     gl.linkProgram(shaderProgram);     // 创建失败, alert     if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {       alert(         "Unable to initialize the shader program: " +           gl.getProgramInfoLog(shaderProgram)       );       return null;     }     return shaderProgram;   }   const shaderProgram = initShaderProgram(gl, vsSource, fsSource);   //   const programInfo = {     program: shaderProgram,     attribLocations: {       vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),     },     uniformLocations: {       projectionMatrix: gl.getUniformLocation(         shaderProgram,         "uProjectionMatrix"       ),       modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),     },   };   // 在绘制图形前,创建缓冲器,存储顶点,然后返回   function initBuffers(gl) {     // 通过createBuffer得到缓冲对象     const positionBuffer = gl.createBuffer();     // 通过bindBuffer绑定上下文     gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);     // 创建数组,记录顶点(为浮点型)     var vertices = [       1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0,     ];     // 通过bufferData创建顶点对象     gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);     return {       position: positionBuffer,     };   }   // 先引入工具库https://cdn.jsdelivr.net/npm/gl-matrix@3.0.0/gl-matrix-min.js   // mat4报错问题参考https://github.com/mdn/sprints/issues/2817   function drawScene(gl, programInfo, buffers) {     // 设置清除颜色     gl.clearColor(0.0, 0.0, 0.0, 1.0);     // 清除深度缓冲区     //文章:https://blog.csdn.net/dizia/article/details/80156765     gl.clearDepth(1.0);     // 启用深度测试     gl.enable(gl.DEPTH_TEST);     // 遮盖深度缓冲区     gl.depthFunc(gl.LEQUAL);     // 清除画布     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);     // 计算角度     const fieldOfView = (45 * Math.PI) / 180; // in radians     const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;     const zNear = 0.1;     const zFar = 100.0;     const projectionMatrix = mat4.create();     mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar);     const modelViewMatrix = mat4.create();     mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -6.0]);     {       const numComponents = 3;       const type = gl.FLOAT;       const normalize = false;       const stride = 0;       const offset = 0;       gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);       gl.vertexAttribPointer(         programInfo.attribLocations.vertexPosition,         numComponents,         type,         normalize,         stride,         offset       );       gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);     }     gl.useProgram(programInfo.program);     gl.uniformMatrix4fv(       programInfo.uniformLocations.projectionMatrix,       false,       projectionMatrix     );     gl.uniformMatrix4fv(       programInfo.uniformLocations.modelViewMatrix,       false,       modelViewMatrix     );     {       const offset = 0;       const vertexCount = 4;       gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);     }   }   drawScene(gl, programInfo, initBuffers(gl)); </script>


作者:外婆桥卖汤
链接:https://juejin.cn/post/7036706674509348900

 伪原创工具 SEO网站优化  https://www.237it.com/ 


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐