webgl学习02-绘制一个点

发布时间 2024-01-12 15:47:14作者: 邢韬

绘制一个点

编写简单的着色器代码

首先,我们先了解一下代码中用到的 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 来说,值越高就越不透明。

着色器代码

首先是顶点着色器

  1. 定义了一个 main 函数
  2. 设置 gl_Position 顶点的三维坐标对应为 (0, 0, 0)
  3. 设置 gl_PointSize 大小为 50 像素
const VertexSource = /* glsl */ `
    void main() {
        gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
        gl_PointSize = 50.0;
    }
`

然后是片元着色器

  1. 同样定义了一个 main 函数
  2. 设置 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);

绘制一个点

接下来是画点

创建着色器

整个部分为

  1. 获取绘图上下文 gl
  2. 编写着色器代码 vertexCode 、 fragmentCode
  3. 创建着色器 createShader
  4. 创建着色器程序 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.POINTSgl.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);

 摘自 iceWebGL | iceWebGL (ice-webgl.netlify.app)