【WebGL】简单入门教程

第1章-介绍

WebGL 解决了用户在页面中绘制和渲染 3D 图形的功能,且使用户通过页面与三维图形交互成为可能,这项技术将在下一代开发用户易用直观界面中发挥重要的作用。在接下的几年,WebGL技术将广泛地应用于电子设备的移动终端,包括平板、手机设备,因此,WebGL 技术的学习显的特别重要。

涉及技术栈

  • HTML、HTML5
  • JavaScript
  • GLSL ES语言

第2章-初识WebGL

2.1 手动绘制一个图形在这里插入图片描述

实现的步骤
  1. 添加一个画布元素
  2. 获取到画布元素的基于webgl上下文环境对象
  3. 使用对象中的API实现图形绘制
代码
  <body>
    <canvas id="cvs" width="200" height="200" style="border: dashed 1px red">
      你的浏览器不支持画布元素
    </canvas>
    <script type="text/javascript">
      //获取画布元素
      var cvs = document.getElementById('cvs')
      //获取到元素的上下文环境对象
      var gl = cvs.getContext('webgl')

      //设置绘制图形填充的颜色
      gl.clearColor(1.0, 0.0, 0.0, 1.0)

      //调用缓存中值填充图形
      gl.clear(gl.COLOR_BUFFER_BIT)
    </script>
  </body>

2.2 使用着色器绘制图形

在这里插入图片描述

WebGL 中的坐标系统

在这里插入图片描述

在这里插入图片描述

着色器的介绍

着色器是使用 OpenGL ES Shading Language 语言编写的程序,负责记录像素点的位置颜色,并由顶点着色器和片段着色器组成,通过用GLSL 编写这些着色器,并将代码文本传递给WebGL执行时编译,另外,顶点着色器和片段着色器的集合我们通常称之为着色器程序

顶点着色器的功能是将输入顶点从原始坐标系转换到WebGL使用的缩放空间坐标系,每个轴的坐标范围从-1.0到1.0,顶点着色器对顶点坐标进行必要的转换后,保存在名称为gl_Position的特殊变量中备用。

片段着色器在顶点着色器处理完图形的顶点后,会被要绘制的每个图形的每个像素点调用一次,它的功能是确定像素的颜色值,并保存在名称为gl_FragColor的特殊变量中,该颜色值将最终绘制到图形像素的对应位置中。

代码
  <body>
    <canvas id="cvs" width="200" height="200" style="border: dashed 1px red">
      你的浏览器不支持画布元素
    </canvas>
    <script type="text/javascript">
      //获取画布元素
      var cvs = document.getElementById('cvs')
      //获取到元素的上下文环境对象
      var gl = cvs.getContext('webgl')

      //顶点着色器变量
      var VSHADER_SOURCE =
        'void main() {' +
        //定义点的坐标并转换成变量保存
        'gl_Position = vec4(0.0, 0.0, 0.0, 1.0); ' +
        //设置缩放距离的直径
        'gl_PointSize = 10.0; ' +
        '} '

      //片段着色器变量
      var FSHADER_SOURCE =
        'void main() {' +
        //设置图形像素的颜色并保存
        'gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);' +
        '}'

      //新建一个用于装顶点字符串的着色器对象
      var vertShader = gl.createShader(gl.VERTEX_SHADER)
      //加载保存好的顶点代码字符串变量
      gl.shaderSource(vertShader, VSHADER_SOURCE)
      //编译顶点着色器
      gl.compileShader(vertShader)

      //新建一个用于装片段字符串的着色器对象
      var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
      //加载保存好的片段代码字符串变量
      gl.shaderSource(fragShader, FSHADER_SOURCE)
      //编译片段着色器
      gl.compileShader(fragShader)

      //新建一个程序
      var shaderProgram = gl.createProgram()

      //分别附加两个已编译好的着色器对象
      gl.attachShader(shaderProgram, vertShader)
      gl.attachShader(shaderProgram, fragShader)

      //链接两个附件加好的着色器程序
      gl.linkProgram(shaderProgram)
      //开启程序的使用
      gl.useProgram(shaderProgram)

      //绘制指定位置的图形
      gl.drawArrays(gl.POINTS, 0, 1)
    </script>
  </body>

第3章-绘制三角形

3.1 多点绘制的方法

在这里插入图片描述

  • 什么attribute 变量

它是一种存储限定符,表示定义一个attribute的全局变量,这种变量的数据将由外部向顶点着色器内传输,并保存顶点相关的数据,只有顶点着色器才能使用它。

  • 使用attribute 变量
  1. 在顶点着色器中,声明一个 attribute 变量。
  2. 将 attribute 变量赋值给 gl_Position 变量。
  3. 向 attribute 变量传输数据。
  • 使用缓存区关联attribute变量
  1. 创建缓存区对象
  2. 绑定缓存区对象
  3. 将数据写入对象
  4. 将缓存区对象分配给attribute变量
  5. 开启attribute变量

3.2 绘制三角形方法

 <body>
    <canvas id="cvs" width="200" height="200" style="border: dashed 1px red">
      你的浏览器不支持画布元素
    </canvas>
    <script type="text/javascript">
      //获取画布元素
      var cvs = document.getElementById('cvs')
      //获取到元素的上下文环境对象
      var gl = cvs.getContext('webgl')

      //顶点着色器变量
      var VSHADER_SOURCE =
        //使用存储限定符定义一个接受顶点坐标的变量
        'attribute vec4 a_Position;' +
        'void main() {' +
        //定义点的坐标并转换成变量保存
        'gl_Position = a_Position; ' +
        '} '

      //片段着色器变量
      var FSHADER_SOURCE =
        'void main() {' +
        //设置图形像素的颜色并保存
        'gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);' +
        '}'

      //新建一个用于装顶点字符串的着色器对象
      var vertShader = gl.createShader(gl.VERTEX_SHADER)
      //加载保存好的顶点代码字符串变量
      gl.shaderSource(vertShader, VSHADER_SOURCE)
      //编译顶点着色器
      gl.compileShader(vertShader)

      //新建一个用于装片段字符串的着色器对象
      var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
      //加载保存好的片段代码字符串变量
      gl.shaderSource(fragShader, FSHADER_SOURCE)
      //编译片段着色器
      gl.compileShader(fragShader)

      //新建一个程序
      var shaderProgram = gl.createProgram()

      //分别附加两个已编译好的着色器对象
      gl.attachShader(shaderProgram, vertShader)
      gl.attachShader(shaderProgram, fragShader)

      //链接两个附件加好的着色器程序
      gl.linkProgram(shaderProgram)
      //开启程序的使用
      gl.useProgram(shaderProgram)
      //定义一个类型数组保存顶点坐标值
      var vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5])
      //先创建一个缓存对象
      var vertexBuffer = gl.createBuffer()
      //说明缓存对象保存的类型
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
      //写入坐标数据
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
      //获取到顶点着色器中变量
      var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')
      //将坐标值赋值给变量
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0)
      //开启变量值的使用
      gl.enableVertexAttribArray(a_Position)

      //绘制指定位置的图形
      gl.drawArrays(gl.TRIANGLES, 0, 3)
    </script>
  </body>

第4章-WebGL动画

4.1 图形移动

在这里插入图片描述

  • 平移原理
    为了平移一个三角形,只需要对它的每个顶点进行移动,即每个顶点加上一个分量,得到一个新的坐标:
    X1=X+TX``Y1=Y+TY``Z1=Z+TZ

只需要着色器中为顶点坐标的每个分量加上一个常量就可以实现,当然这这修改在顶点着色器上。

  • uniform类型变量
    用于保存和传输一致的数据,既可用于顶点,也可用于片断。
  <body>
    <canvas id="cvs" width="200" height="200" style="border: dashed 1px red">
      你的浏览器不支持画布元素
    </canvas>
    <script type="text/javascript">
      //获取画布元素
      var cvs = document.getElementById('cvs')
      //获取到元素的上下文环境对象
      var gl = cvs.getContext('webgl')

      //顶点着色器变量
      var VSHADER_SOURCE =
        //使用存储限定符定义一个接受顶点坐标的变量
        'attribute vec4 a_Position;' +
        //使用存储限定符定义一个接受一致偏移量的变量
        'uniform vec4 u_Translation;' +
        'void main() {' +
        //定义点的坐标并转换成变量保存
        'gl_Position = a_Position + u_Translation; ' +
        '} '

      //片段着色器变量
      var FSHADER_SOURCE =
        'void main() {' +
        //设置图形像素的颜色并保存
        'gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);' +
        '}'

      //新建一个用于装顶点字符串的着色器对象
      var vertShader = gl.createShader(gl.VERTEX_SHADER)
      //加载保存好的顶点代码字符串变量
      gl.shaderSource(vertShader, VSHADER_SOURCE)
      //编译顶点着色器
      gl.compileShader(vertShader)

      //新建一个用于装片段字符串的着色器对象
      var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
      //加载保存好的片段代码字符串变量
      gl.shaderSource(fragShader, FSHADER_SOURCE)
      //编译片段着色器
      gl.compileShader(fragShader)

      //新建一个程序
      var shaderProgram = gl.createProgram()

      //分别附加两个已编译好的着色器对象
      gl.attachShader(shaderProgram, vertShader)
      gl.attachShader(shaderProgram, fragShader)

      //链接两个附件加好的着色器程序
      gl.linkProgram(shaderProgram)
      //开启程序的使用
      gl.useProgram(shaderProgram)
      //定义一个类型数组保存顶点坐标值
      var vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5])
      //先创建一个缓存对象
      var vertexBuffer = gl.createBuffer()
      //说明缓存对象保存的类型
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
      //写入坐标数据
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
      //获取到顶点着色器中变量
      var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')
      //将坐标值赋值给变量
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0)
      //开启变量值的使用
      gl.enableVertexAttribArray(a_Position)

      //定义各坐标点的统一偏移量
      var Tx = 0.2,
        Ty = 0.3,
        Tz = 0.0
      //获取到顶点着色器中uniform变量
      var u_Translation = gl.getUniformLocation(shaderProgram, 'u_Translation')
      //将多个偏移量赋值值给uniform变量
      gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0)

      //绘制指定位置的图形
      gl.drawArrays(gl.TRIANGLES, 0, 3)
    </script>
  </body>

4.2 图形旋转

在这里插入图片描述

旋转原理
为了描述一个图形的旋转过程,必须指明以下内容:

  1. 旋转轴(围绕X和Y轴旋转)
  2. 旋转的方向(顺时针和逆时针),负值是为顺时针,正值时为逆时针
  3. 旋转的角度(图形经过的角度)
    在这里插入图片描述
    在这里插入图片描述

4.3 图形缩放

在这里插入图片描述

  • 缩放的原理
    通过改变原有图形中的矩阵值,实现图形的拉大和缩下效果,因此,只需要修改原有图形的矩阵值即可。
    在这里插入图片描述

  • 动画实现

    需求:制作一个按旋转三角形的动画

    效果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MmKI0duN-1649683016895)(/Users/taoguorong/Documents/Snagit/页面高性能图形编程/01 笔记/img/2019-03-29_15-13-39_01.jpg)]

屏幕刷新频率
图像在屏幕上更新的速度,也即屏幕上的图像每秒钟出现的次数,一般是60Hz的屏幕每16.7ms刷新一次。
动画原理
图像被刷新时,引起以连贯的、平滑的方式进行过渡变化。
核心方法

  requestAnimationFrame(callback)
  //执行一个动画,并在下次绘制前调用callback回调函数更新该动画

第5章-WebGL颜色

5.1 操作步骤介绍

在这里插入图片描述

  • 颜色添加步骤
  1. 在顶点着色器中定义一个接收外部传入颜色值的属性变量a_Color和用于传输获取到的颜色值变量v_Color
  2. 在片段着色器中定义一个同一类型和名称的v_Color变量接收传顶点传入的值。
  3. 重新传入到顶点坐标和颜色值的类型化数组
  4. 将数组值传入缓存中并取出,赋值给顶点的两个变量
  5. 接收缓存值并绘制图形和颜色
  • vertexAttribPointer 方法

  • 参数说明
    第1个参数指定待分配attribute变量的存储位置
    第2个参数指定缓存区中每个顶点的分量个数(1~4)
    第3个参数类型有,无符号字节,短整数,无符号短整数,整型,无符号整型,浮点型
    第4个参数表示是否将非浮点型的数据归到[0,1][-1,1]区间
    第5个参数相邻两个顶点的字节数。默认为0
    第6个参数表示缓存区对象的偏移量(以字节为单位),attribute 变量从缓冲区中的何处开始存储
  • 案例实现

  1. 添加画布元素,并获取webGL对象,保存在变量中。
  2. 定义着色器内容,并进行附件编译。
  3. 使用缓存对象向顶点传入多个坐标数据。
  4. 根据坐标数据绘制图像。

5.2 着色器编译与图像绘制

  <body>
    <canvas id="cvs" width="200" height="200" style="border: dashed 1px red">
      你的浏览器不支持画布元素
    </canvas>
    <script type="text/javascript">
      //获取画布元素
      var cvs = document.getElementById('cvs')
      //获取到元素的上下文环境对象
      var gl = cvs.getContext('webgl')

      //顶点着色器变量
      var VSHADER_SOURCE =
        //使用存储限定符定义一个接受顶点坐标的变量
        'attribute vec4 a_Position;' +
        'attribute vec4 a_Color;' +
        'varying vec4 v_Color;' +
        'void main() {' +
        //定义点的坐标并转换成变量保存
        'gl_Position = a_Position; ' +
        'v_Color = a_Color; ' +
        '} '

      //片段着色器变量
      var FSHADER_SOURCE =
        'precision mediump float;' +
        'varying vec4 v_Color;' +
        'void main() {' +
        //设置图形像素的颜色并保存
        'gl_FragColor = v_Color ;' +
        '}'

      //新建一个用于装顶点字符串的着色器对象
      var vertShader = gl.createShader(gl.VERTEX_SHADER)
      //加载保存好的顶点代码字符串变量
      gl.shaderSource(vertShader, VSHADER_SOURCE)
      //编译顶点着色器
      gl.compileShader(vertShader)

      //新建一个用于装片段字符串的着色器对象
      var fragShader = gl.createShader(gl.FRAGMENT_SHADER)
      //加载保存好的片段代码字符串变量
      gl.shaderSource(fragShader, FSHADER_SOURCE)
      //编译片段着色器
      gl.compileShader(fragShader)

      //新建一个程序
      var shaderProgram = gl.createProgram()

      //分别附加两个已编译好的着色器对象
      gl.attachShader(shaderProgram, vertShader)
      gl.attachShader(shaderProgram, fragShader)

      //链接两个附件加好的着色器程序
      gl.linkProgram(shaderProgram)
      //开启程序的使用
      gl.useProgram(shaderProgram)
      //定义一个类型数组保存顶点坐标值
      var vertices = new Float32Array([
        //  x,   y,   red, green, blue
        0.0, 0.5, 1.0, 0.0, 0.0, -0.5, -0.5, 0.0, 1.0, 0.0, 0.5, -0.5, 0.0, 0.0,
        1.0,
      ])
      //先创建一个缓存对象
      var vertexBuffer = gl.createBuffer()
      //说明缓存对象保存的类型
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
      //写入坐标数据
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
      //获取到数组中单个元素的字节数
      var FSIZE = vertices.BYTES_PER_ELEMENT

      //获取到顶点着色器中变量
      var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position')
      //将坐标值赋值给变量
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0)
      //开启变量值的使用
      gl.enableVertexAttribArray(a_Position)

      //获取到顶点着色器中变量
      var a_Color = gl.getAttribLocation(shaderProgram, 'a_Color')
      //将坐标值赋值给变量
      gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2)
      //开启变量值的使用
      gl.enableVertexAttribArray(a_Color)

      //绘制指定位置的图形
      gl.drawArrays(gl.TRIANGLES, 0, 3)
    </script>
  </body>
  • 39
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
目 录 第1章 WebGL简介 1 1.1 WebGL——一个技术定义 2 1.2 3D图形学——入门 4 1.2.1 3D坐标系 4 1.2.2 网格、多边形和顶点 5 1.2.3 材质、纹理和光源 5 1.2.4 变换与矩阵 6 1.2.5 相机、透视、视口和投影 6 1.2.6 着色器 7 1.3 WebGL原生API 8 1.3.1 WebGL应用结构剖析 9 1.3.2 画布元素与绘制上下文 9 1.3.3 视口 10 1.3.4 Buffer、ArrayBuffer和类型化数组 10 1.3.5 矩阵 11 1.3.6 着色器 12 1.3.7 绘制图元 13 1.4 本章小结 14 第2章 你的第一个WebGL程序 15 2.1 Three.js——一个JavaScript 3D引擎 15 2.2 建立Three.js运行环境 17 2.3 一个简单的Three.js网页 17 2.4 一个真实的3D示例 20 2.4.1 为场景着色 23 2.4.2 添加纹理映射 24 2.4.3 旋转物体 25 2.4.4 循环重绘和requestAnimationFrame() 25 2.4.5 让页面贴近生活 26 2.5 本章小结 27 第3章 图形 28 3.1 Sim.js——一个轻量级的WebGL模拟框架 29 3.2 创建网格 30 3.3 使用材质、纹理和光源 34 3.3.1 光源的种类 35 3.3.2 使用多重纹理创建更具真实感的场景 37 3.3.3 纹理与透明 42 3.4 构建变换层级 42 3.5 创建自定义几何体 46 3.6 点和线的渲染 49 3.6.1 使用粒子系统绘制点 50 3.6.2 线的绘制 52 3.7 编写着色器 53 3.7.1 WebGL着色器基础 53 3.7.2 Three.js中的着色器 55 3.8 本章小结 60 第4章 动画 61 4.1 动画基础 61 4.1.1 帧动画 61 4.1.2 时间动画 62 4.1.3 插值与补间动画 62 4.1.4 关键帧 63 4.1.5 关节动画 64 4.1.6 蒙皮动画 64 4.1.7 目标变形动画 64 4.2 使用Tween.js库来创建补间动画 65 4.2.1 创建一个基本的补间动画 66 4.2.2 带缓动效果的补间动画 68 4.3 为带关节的模型制作关键帧动画 71 4.3.1 载入模型 71 4.3.2 为模型制作动画 73 4.4 材质和光源动画 76 4.5 纹理动画 78 4.6 蒙皮动画和变形动画 80 4.7 本章小结 80 第5章 交互 81 5.1 点击检测、拾取和投影 81   Three.js中的点击检测 82 5.2 处理鼠标移入和点击 85 5.3 处理拖曳 88   在拖曳中使用补间动画 91 5.4 使用点击点和法线信息 91 5.5 基于相机的交互 92 5.5.1 利用镜头控制制作一个模型浏览器 93 5.5.2 场景漫游 95 5.6 本章小结 96 第6章 2D与3D的整合 98 6.1 整合动态HTML和WebGL 99 6.1.1 创建DIV元素弹出层 99 6.1.2 利用2D屏幕坐标为3D物体添加注释 103 6.1.3 为3D场景添加背景图片 104 6.2 在2D页面上插入3D浮层 105 6.3 利用2D Canvas创建动态纹理 107 6.4 使用视频作为纹理 115 6.5 渲染动态3D文字 119 6.6 WebGL中的终极整合 121 6.7 本章小结 123 第7章 实战WebGL 124 7.1 如何选择运行库和框架 124 7.2 载入3D内容 126 7.2.1 COLLADA:数字资产交换格式 126 7.2.2 Three.js中的JSON模型文件格式 130 7.2.3 Three.js二进制模型文件格式 134 7.2.4 压缩3D模型 135 7.2.5 Three.js中的JSON场景文件格式 136 7.3 创建3D内容 137 7.3.1 从Blender中导出3D内容 137 7.3.2 把OBJ文件转换为Three.js JSON文件 139 7.3.3 把OBJ文件转换为Three.js二进制文件 139 7.3.4 其他软件或格式的转换 139 7.4 浏览器支持度 140 7.4.1 检测浏览器的WebGL支持 141 7.4.2 在Safari中开启WebGL支持 142 7.5 处理丢失上下文事件 143 7.6 WebGL的安全性 146 7.7 本章小结 149 第8章 你的第一个WebGL游戏 150 8.1 构建游戏的各个部分 151 8.1.1 相机、角色和控制 152 8.1.2 美术设计 159 8.1.3 模型预览器 161 8.1.4 创建粒子系统 163 8.1.5 添加声音 166 8.2 万物归一 167 8.3 本章小结 180 后记 181 附录A WebGL在线资源 183

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小沈曰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值