前言
上篇介绍了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可以绘制的图形,即点、线、三角形。下文将介绍线的绘制,并且讲述缓冲区等概念。