Measuring shaders performance with stats.js

Hi, I’m using the stats.js module to measure FPS of my Three.js app.
I’m using textures to compute a particle simulation, so as I increase the texture size the FPS goes down as expected.

But when I click the stats component to change to the “ms” mode even though the FPS counter is around 30 the number of milliseconds per frame is less than 1. And obviously, it should be over 30 ms

Then I used the performance tool on Chrome, and to my surprise, the GPU task seems to be taking less than a 1 ms (see attached picture)

  1. How can I know the real amount of time is taking to render a frame?
  2. If the rendering is really taking less than 1 ms, by the FPS are below 60?
  3. Does anyone know a better way to measure the rendering performance and profile WebGL shader?


What happens on GPU itself isn’t profiled, for GPU-side expensive tasks and shaders you basically only get a huge idle of nothingness with the CPU waiting. The 1-36ms in stats rather refers to the average span recorded.

I’ve made a plugin few days ago to visualize draw call cost, it doesn’t give or estimates timings yet, but you will see a weighting of every mesh being rendered how costly it is compared with each other. However, you might check your code first for obvious highly costly operations first, especially with particles and massive overdraw you can make GPUs sweat easily.

I’m using textures to compute a particle simulation, so as I increase the texture size the FPS goes down as expected.

Can you explain this in more detail? What size and what are you computing? Are you using the gpgpu renderer?

1 Like

Hi, thanks for your answer. I’ll take a look at your plugin.

I’m still curious about why the the measure of the time elapsed between stats.begin() and stats.end() is not right. If the idle time period is of around 30 ms and stats compares de 2 timestamps. It should give a correct value

About the particle simulation on the GPU, I build my own class that uses float 32bit textures (actually 2 textures read & write) and a pixel shader to update the pixels. Each pixel represents the XYZ coordinates of a particle. Then I use the texture on a vertex to define the position of each quad vertex.
I use one single mesh with as many quads as particles represented by the texture. So i execute only one draw call for the whole particle’s cloud.
Here are some images & videos of the results