webgl学习02-绘制一个点
绘制一个点
编写简单的着色器代码
首先,我们先了解一下代码中用到的 GLSL 语言的 类型 和 内置变量。
顶点着色器
用到的数据类型
顶点着色器的内置变量
内置函数
gl_Position
的类型—— vec4
明显比 gl_PointSize
的 float
要特别。如果说我们需要的顶点坐标数据是 (x, y, z)
,那么好像也才只有 3 个浮点数,那第 4 个数是什么呢?
通常,我们添加 1.0
作为第四个参数 w
,也就是 (x, y, z, 1.0)
。由四个数组成的矢量叫做 齐次坐标,齐次坐标 (x, y, z, w)
其实等价于三维坐标 (x/w, y/w, z/w)
。抛开这么多复杂的概念,我们当前只需要明确一点:当我们使用齐次坐标表示三维顶点坐标时,最后一个值传 1.0
即可。
片元着色器
片元着色器的内置变量
当然,片元着色器中 gl_FragColor
的值类型是 vec4
就很好理解了,因为其一一对应 RGBA
中的每一位。需要注意的是 WebGL 继承 OpenGl 的颜色取值,它的范围是 (0.0, 1.0)
,RGB
的值越高颜色越亮,而对于透明度 A
来说,值越高就越不透明。
着色器代码
首先是顶点着色器
- 定义了一个
main
函数 - 设置
gl_Position
顶点的三维坐标对应为 (0, 0, 0) - 设置
gl_PointSize
大小为 50 像素
const VertexSource = /* glsl */ ` void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 50.0; } `
然后是片元着色器
- 同样定义了一个
main
函数 - 设置
gl_FragColor
的值为蓝色(R=0, G=0, B=0.9, A=1)
const FragSource = /* glsl */ ` void main() { gl_FragColor = vec4(0.0, 0.0, 0.9, 1.0); } `
清空绘图区
清空绘图区代码
清空绘图区其实就是清空颜色缓冲区,所以接口 gl.clear
的参数中,我们仅需要使用 gl.COLOR_BUFFER_BIT
,其他的可以先不用管。
需要注意,gl.clearColor(r, g, b, a)
是有记忆的,如果我们后续清空绘图区的颜色不需要改变,那我们只需要 指定一次 clearColor
即可
const canvas = document.querySelector("#c"); const gl = canvas.getContext("webgl"); // 设置 canvas 背景色(若无需变化颜色,则只需要设置一次即可) gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清空 canvas gl.clear(gl.COLOR_BUFFER_BIT);
绘制一个点
接下来是画点
创建着色器
整个部分为
- 获取绘图上下文
gl
- 编写着色器代码
vertexCode
、fragmentCode
- 创建着色器
createShader
- 创建着色器程序
createProgram
连接顶点、片元着色器
// 顶点着色器 const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, VertexSource); gl.compileShader(vertexShader); // 片元着色器 const fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, FragSource); gl.compileShader(fragShader); // 创建着色器程序 const program = gl.createProgram(); // 为着色器程序赋予shader gl.attachShader(program, vertexShader); gl.attachShader(program, fragShader); // 连接 顶点着色器 和 片元着色器 gl.linkProgram(program); // 应用着色器程序 gl.useProgram(program);
绘制点
调用绘制函数 gl.drawArrays
并传入一定参数即可完成点的绘制
mode
总共有七种参数值,包括且不限于 gl.POINTS
、gl.LINE_STRIP
等等
绘制代码:
// 绘制点 gl.drawArrays(gl.POINTS, 0, 1);
完整代码
const VertexSource = /* glsl */ ` void main() { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_PointSize = 50.0; } ` const FragSource = /* glsl */ ` void main() { gl_FragColor = vec4(0.0, 0.0, 0.9, 1.0); } ` const canvas = document.querySelector("#c"); const gl = canvas.getContext("webgl"); // 设置 canvas 背景色(若无需变化颜色,则只需要设置一次即可) gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清空 canvas gl.clear(gl.COLOR_BUFFER_BIT); // 顶点着色器 const vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, VertexSource); gl.compileShader(vertexShader); // 片元着色器 const fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, FragSource); gl.compileShader(fragShader); // 创建着色器程序 const program = gl.createProgram(); // 为着色器程序赋予shader gl.attachShader(program, vertexShader); gl.attachShader(program, fragShader); // 连接 顶点着色器 和 片元着色器 gl.linkProgram(program); // 应用着色器程序 gl.useProgram(program); // 绘制点 gl.drawArrays(gl.POINTS, 0, 1);