WebGL学习之路:2. WebGL的第一个程序——画一个点

前言

上篇介绍了WebGL的基本概念和基础知识,本文记录一下怎么实现WebGL的第一个程序,通过绘制图元来继续介绍WebGL的api使用。

绘图

初始化

初始化其实就是把上文的代码再写一遍,然后开始绘制图形:

  • 创建画布
html 复制代码
<canvas id="canvas" width="500" height="500"></canvas>
  • 编写着色器代码
html 复制代码
<!-- 顶点着色器 -->
  <script id="vertex-shader" type="x-shader/x-vertex">
    void main() {
     gl_PointSize = 10.0;
     gl_Position = vec4(0.0, 0.0, 1.0, 1.0);
    }
  </script>

  <!-- 片段着色器 -->
  <script id="fragment-shader" type="x-shader/x-fragment">
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  </script>
  • 创建着色器程序
js 复制代码
    // 1. 获取canvas元素和webgl上下文
    const canvas = document.getElementById("canvas")
    const gl = canvas.getContext("webgl")
    // 2. 创建着色器对象
    const vertexShader = gl.createShader(gl.VERTEX_SHADER)
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
    // 3. 获取着色器源码
    const vertexSource = document.getElementById('vertex-shader').innerText
    const fragmentSource = document.getElementById('fragment-shader').innerText
    // 4. 绑定着色器源码然后编译
    // 绑定
    gl.shaderSource(vertexShader, vertexSource)
    gl.shaderSource(fragmentShader,fragmentSource)
    // 编译
    gl.compileShader(vertexShader)
    gl.compileShader(fragmentShader)
    // 5. 创建程序对象
    const program = gl.createProgram()
    gl.attachShader(program, vertexShader)
    gl.attachShader(program, fragmentShader)
    gl.linkProgram(program)
    gl.useProgram(program)
  • 绘制

然后就到了本文的重点内容,绘制图形------画一个点,画图之前,先看一下WebGL是怎样绘制图元的:

WebGL只能绘制绘制三种形状:点、线、三角形。其他形状必须通过这三种基本形状在3D空间的组合来绘制,WebGL绘图要使用gl.drawArrays()gl.drawElements()方法,前者使用缓冲数组,后者使用操作元素数组缓冲区。(所有提到的gl都代表WebGL的上下文,重要的是后边的方法),缓冲区会在下文介绍。

gl.drawArrays()gl.drawElements()方法的第一个参数都代表要绘制的形状的常量,参数如下:

  • gl.POINTS:将每个顶点当成一个点来绘制
  • gl.LINES:将数组作为一系列顶点,在这些顶点间绘制直线,每个顶点既是起点也是终点,所以数组中的顶点必须是偶数才能开始绘制。
  • gl.LINE_LOOP:将数组作为一系列顶点,在这些顶点间绘制直线,从第一个顶点到第二个顶点绘制一条直线,再从第二个顶点到第三个顶点绘制一条直线,以此类推,到最后一个顶点,再从最后一个顶点到第一个顶点绘制一条直线。
  • gl.LINE_STRIP:和gl.LINE_LOOP的区别就是不会从最后一个顶点到第一个顶点再绘制一条直线
  • gl.TRIANGLES:将数组作为一系列顶点,在这些顶点间绘制三角形,如果不特殊指定,每个三角形都分开绘制,不共享顶点
  • gl.TRIANGLES_STRIP:和gl.TRIANGLES的区别是,在前3个顶点之后的顶点会作为第三个顶点与其前面的两个顶点构成三角形。例如,数组中的顶点是A、B、C、D,那么第一个三角形使用ABC,第二个三角形使用BCD。
  • gl.TRIANGLES_FAN:和gl.TRIANGLES的区别是,在前3个顶点之后的顶点会作为第三个顶点与其前面的顶点第一个顶点构成三角形。例如,数组中的顶点是A、B、C、D,那么第一个三角形使用ABC,第二个三角形使用BCD。

这些参数就是gl.drawArrays()gl.drawElements()方法可以接受的参数,那么现在传入gl.POINTS参数来绘制点:

js 复制代码
gl.drawArrays(gl.POINTS, 0, 1)

第二个参数代表数组缓冲区的起点索引,第三个参数代表数组缓冲区包含的顶点集合的数量,因为只画一个点,所以相当于没有用到数组缓冲区,所以缓冲区这里先不介绍,下文将介绍缓冲区。画图如下:

图中边框就是canvas的区域,片段着色器代码中设置了颜色为(1.0, 0.0, 0.0, 1.0),对应rgba也就是红色,所以这里绘制出了一个红色的点。

总结

本文通过绘制一个红色点的实践,串联了 WebGL 的核心渲染流程,如下图: 并介绍了WebGL可以绘制的图形,即点、线、三角形。下文将介绍线的绘制,并且讲述缓冲区等概念。

相关推荐
kidding7239 分钟前
微信小程序怎么分包步骤(包括怎么主包跳转到分包)
前端·微信小程序·前端开发·分包·wx.navigateto·subpackages
微学AI23 分钟前
详细介绍:MCP(大模型上下文协议)的架构与组件,以及MCP的开发实践
前端·人工智能·深度学习·架构·llm·mcp
liangshanbo12151 小时前
CSS 包含块
前端·css
Mitchell_C1 小时前
语义化 HTML (Semantic HTML)
前端·html
倒霉男孩1 小时前
CSS文本属性
前端·css
晚风3081 小时前
前端
前端
JiangJiang1 小时前
🚀 Vue 人如何玩转 React 自定义 Hook?从 Mixins 到 Hook 的华丽转身
前端·react.js·面试
鱼樱前端1 小时前
让人头痛的原型和原型链知识
前端·javascript
用户19727304821961 小时前
传说中的开发增效神器-Trae,让我在开发智能旅拍小程序节省40%时间
前端
lianghj1 小时前
前端高手必备:深度解析高频场景解决方案与性能优化实战
前端·javascript·面试