RedHawk96 Posted May 3, 2016 Share Posted May 3, 2016 Hello, I'm kinda new to WebGL in general, I've started to make some batching experiences on primitives (just drawing 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: Why is the batcher having worst results? What can be optimized to have an optimal drawing performance? Isn't it weird I'm having so low FPS with so few triangles? Best Regards. Quote Link to comment Share on other sites More sharing options...
mfdesigner Posted May 3, 2016 Share Posted May 3, 2016 ANGLE_instanced_arrays is what you need. http://blog.tojicode.com/2013/07/webgl-instancing-with.html Quote Link to comment Share on other sites More sharing options...
RedHawk96 Posted May 3, 2016 Author Share Posted May 3, 2016 Thanks a lot, that was the exact kind of information I was looking for. I improved several parts and now I'm getting much better results! Basically changed all the positions/scaling to be made using matrices and used a base rectangle structure: var rectangleData = [ 0.0, 1.0, 0.0, // TOP LEFT 0.0, 0.0, 0.0, // BOTTOM LEFT 1.0, 0.0, 0.0, // BOTTOM RIGHT 1.0, 1.0, 0.0, // TOP RIGHT 0.0, 1.0, 0.0, // TOP LEFT 1.0, 0.0, 0.0 // BOTTOM RIGHT ]; Besides that, I've modified to color attribute, which is now an uniform, and other particularities of the rendering process as said in the article. Quote Link to comment Share on other sites More sharing options...
ericjbasti Posted June 1, 2016 Share Posted June 1, 2016 Are you creating 2 new float32arrays on every frame? You should reuse them as much as possible. Create them someplace outside the scope of your drawing call, and reference them over and over again. Creating new float32arrays is really slow, and surely killing your memory load. Quote Link to comment Share on other sites More sharing options...
RedHawk96 Posted June 2, 2016 Author Share Posted June 2, 2016 16 hours ago, ericjbasti said: Are you creating 2 new float32arrays on every frame? You should reuse them as much as possible. Create them someplace outside the scope of your drawing call, and reference them over and over again. Creating new float32arrays is really slow, and surely killing your memory load. That's one of the changes I've made later on, it helped to improve the performance too Thanks! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.