1
\$\begingroup\$

I'm kinda new to WebGL in general, I've started to make some batching experiences on primitives (just drying a bunch of rectangles by using a combination of two triangles repeatedly).

I've started by implementing Direct Drawing that draws a rectangle (TRIANGLE_STRIP like) as soon it is requested:

  var colorArr = new Float32Array(<color values here>);

    var vertices = [
        rectangle.x, rectangle.y, 0.0,                                              // TOP LEFT
        rectangle.x, rectangle.y + rectangle.height, 0.0,                           // BOTTOM LEFT
        rectangle.x + rectangle.width, rectangle.y, 0.0,                        // TOP RIGHT
        rectangle.x + rectangle.width, rectangle.y + rectangle.height, 0.0        // BOTTOM RIGHT
    ];

    _this.game.getShaderManager().useShader(_this.primitiveShader);

    // position buffer
    gl.bindBuffer(gl.ARRAY_BUFFER, _this.vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);


    gl.enableVertexAttribArray(_this.primitiveShader.attributes.aVertexPosition);
    gl.vertexAttribPointer(_this.primitiveShader.attributes.aVertexPosition, 3, _this.gl.FLOAT, false, 0, 0);

    // color buffer
    gl.bindBuffer(gl.ARRAY_BUFFER, _this.colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, colorArr, gl.STATIC_DRAW);

    gl.enableVertexAttribArray(_this.primitiveShader.attributes.aColor);
    gl.vertexAttribPointer(_this.primitiveShader.attributes.aColor, 4, _this.gl.FLOAT, false, 0, 0);

    // set uniforms
    gl.uniformMatrix4fv(_this.primitiveShader.uniforms.uMatrix._location, false, _this.game.getActiveCamera().getMatrix());

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

But then I wanted to go one step further and I've implemented a simple batcher (mostly by common sense, which is probably where I started wrong).

Basically the batcher does the same thing has the code above, the difference is that I concat all the vertex and color data into a big array of data and then draw everything:

    // position buffer
        gl.bindBuffer(gl.ARRAY_BUFFER, _this.vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(_this.rectangleVertexData), gl.STATIC_DRAW);

        gl.enableVertexAttribArray(_this.primitiveShader.attributes.aVertexPosition);
        gl.vertexAttribPointer(_this.primitiveShader.attributes.aVertexPosition, 3, _this.gl.FLOAT, false, 0, 0);

        // color buffer
        gl.bindBuffer(gl.ARRAY_BUFFER, _this.colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(_this.rectangleColorData), gl.STATIC_DRAW);

        gl.enableVertexAttribArray(_this.primitiveShader.attributes.aColor);
        gl.vertexAttribPointer(_this.primitiveShader.attributes.aColor, 4, _this.gl.FLOAT, false, 0, 0);

        // set uniforms
        gl.uniformMatrix4fv(_this.primitiveShader.uniforms.uMatrix._location, false, cameraMatrix);

        gl.drawArrays(gl.TRIANGLES, 0, 6 * _this.rectangleCount);

For my surprise, the second attempt is getting worst results. Using the first approach I get a solid 60 fps on a 320 rectangles drawing and on the second only 40 fps.

So, my questions specifically are:

  1. Why is the batcher having worst results?
  2. What can be optimized to have an optimal drawing performance?

Best Regards.

\$\endgroup\$
1
  • \$\begingroup\$ You can improve performance some by using gl.bufferSubData() instead of bufferData() to replace the vertices each time. It uses the same buffer without reallocating. \$\endgroup\$ Commented Apr 30, 2016 at 18:16

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.