5
votes

To experiment with WebGL, I've written a script that renders a bunch of 2D sprites on a canvas. All the sprites are just textured rectangles.The texture on each rectangle is the same. They change their positions randomly with each frame.

I'm seeing a strange issue on Windows: in Chrome, the framerate is almost 2 times lower than in Firefox (on Mac, Chrome and Firefox have similar framerates). Is there a known problem in the Windows build of Chrome that affects WebGL performance?

Another issue is that when I increase the sprite count from about 500 to 5000, the framerate drops from almost 60 to 20-30 frames per second. Correct me if I'm wrong, but shouldn't rendering 5000 textured quads be a relatively light workload for modern graphic cards? Modern games that operate at 30 fps probably have MUCH higher polygon count.

Here's how my rendering works:

  1. I create three WebGL buffers: for vertex positions, texture coodinates and vertex indices. Each of these buffers has more than enough space to accomodate for 5000 sprites. I also create in-memory typed arrays to hold vertex positions, texture coords and indices (Float32Array for vertices and texture coords, Uint16Array for indices).

  2. On each frame, when adding a sprite, I write vertex, texture coord and index data into the in-memory arrays (at this point, no WebGL calls occur).

  3. At the end of the frame, I upload the data from the in-memory arrays into the WebGL buffers using bufferSubData and call drawElements.

Am I doing something wrong? Shouldn't the framerate be pretty high for 5k sprites? And finally, why is the framerate lower in Chrome than in Firefox?

1

1 Answers

1
votes

I don't suppose you could post a link to a live demo of your code? That would be helpful in determining where the performance issues lie.

As for the difference between Chrome and Firefox, it could be any number of things but one possibility that jumps to mind is the performance of TypedArrays. Firefox and Chrome have different performance characteristics regarding TypedArray construction/use, which could be causing some of the performance difference you are seeing if you use them heavily (which is sounds like you are). It should also be noted that uploading ~0.5Mb of vertex and index data (estimated based on your description) to your GPU per frame isn't going to be the fastest thing in the world. Shouldn't be cripplingly slow, but it won't be fast.

My recommendation is to try and rule out the possible issues one by one: First try rendering 5000 static textured quads without updating the vertex data each frame. Is performance still different? Then it may be some quirk of your vertex format or shaders.

If they perform the same, try re-enabling the update step but only build the in-memory arrays, don't upload them. If there's a performance difference now then you should look at finding ways to reduce buffer churn. (ie: Don't create a new buffer every frame if you are, etc.)

If the performance still isn't different, then the upload step may be the cause. This is trickier to work around (and you should file a Chrome bug describing the situation and where it's slower than Firefox) but you could potentially reduce the amount of buffer uploads by looking into instancing or using uniform arrays instead of updating vertexes for positions/textures.

Hopefully this helps you find your bottleneck!