WebGL 入门爽系列1 gl.drawArrays

2,866 阅读2分钟

WebGL比canvas2d 绘图爽的地方就在于性能,性能,性能!经过简单对比之后,就发现性能不是一个数量级的。

入门函数 gl.drawArrays

而从最简单的gl.drawArrays 函数入手,应该是最简单有趣的学习方式吧。 gl.drawArrays 这个函数是最终负责渲染的webgl核心函数,参数定义为:

gl.drawArrays(mode: gl.mode, start:number, count:number)

webgl绘图mode表

直接上最简单的代码,然后慢慢体会其中奥秘

  var gl = getWebglContext(canvas); // : WebGLRenderingContext
  // extern method, bind gl with Shaders..
  if (!initShaders(gl, vshader, fshader)) {
    console.log("failed to init shaders..");
    return;
  }

  // 获取 Attribute 变量的存储位置
  var a_Position = gl.getAttribLocation(gl.program, "a_Position");
  var u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");
  if (a_Position < 0 || u_FragColor < 0) {
    console.log("failed to get the storage location of a_Position");
    return;
  }

  var positions = [];
  var num = 10000;
  for (var j = 0; j < num; j +=1) {
    // 1w points
    positions.push([Math.random() * 2 - 1, Math.random() * 2 - 1]);
  }

  gl.clearColor(0.1, 0.1, 0.1, 1);

  // use previous clearColor to clear canvas ! if no clearColor, default.
  gl.clear(gl.COLOR_BUFFER_BIT);

  for (var ii = 0; ii < positions.length; ii++) {
    // 给顶点渲染器传递点坐标,2f表示两个浮点型数值作为一个顶点的x, y坐标.. 
    gl.vertexAttrib2f(a_Position, positions[ii][0], positions[ii][1]);
    if (positions[ii] instanceof Array && positions[ii].length > 1) {
        if (positions[ii][0] > positions[ii][1]) {
            // uniform4f , pass vec4 to u_FragColor in FragShader.
            //// uniform4f 给片元着色器传颜色值,0~1 对应与0~255 RGBA 4个波段 
            gl.uniform4f(u_FragColor, 0.9, 0.6, 0.3, 1);
        } else {
            gl.uniform4f(u_FragColor, 0.6, 0.8, 0.9, 1);
        }
    }
    // 每次渲染一个点,看看最开始的函数定义,第二个参数表明从哪个数值开始画,第三个参数表明画几个点。
    gl.drawArrays(gl.POINTS, 0, 1);
  }

稍加解释

每次经过 gl.vertextAttrib2f 函数之后,gl顶点内存中只有顶点。此时再调用 gl.drawArrays(gl.POINTS, 0, 1),第二个参数表明从哪个顶点开始画,第三个参数表明画几个点(有没有觉得用法像 Array.slice(start, end) ?! )。针对gl.POINTS 模式,画一个点只需要一个顶点。所以就传入0,1.效果如下图:

1w webgl point

在线体验

可以看出来,1万个顶点渲染,没用到glBuffer 的情况下,可以跑到30Fps的动画帧率,还是不错的。用glBuffer的形式可以让*帧率达到60Fps, 而同样画1万个顶点,用canvas2d 只能在20Fps左右。所以还是web GL 爽啊!!!

这么简单,下次还是继续学点有意思的,比如gl.TRIANGLESgl.LINE_LOOP.

参考

《WebGL 编程指南》