Pixel Overdraw

Hi. I prepared simple script components that can help you to understand if your scenes have massive pixel overdraw.

Playcanvas Project: PlayCanvas 3D HTML5 Game Engine
Github: GitHub - querielo/playcanvas-overdraw

Playcanvas Typescript Template:


Pixel overdraw refers to the number of times a pixel is drawn on top of itself. Keeping pixel overdraw as low as possible is important for several reasons:

  1. Performance: Overdraw can greatly slow down the performance of a game or application, as it requires the GPU to do more work.
  2. Battery life: Overdraw can also have a significant impact on battery life, as it requires more power to draw more pixels.
  3. Quality: Overdraw can also lead to visual artifacts, such as flickering or aliasing, which can negatively impact the visual quality of the game or application.

To reduce pixel overdraw, it is important to make sure that objects in the scene are properly sorted, and that objects that are obscured by others are not drawn. Additionally, techniques such as culling and occlusion can be used to further reduce the number of pixels that need to be drawn.

NOTE: reducing overdraw can help only if fragment shaders are your bottleneck. So, always use the Playcanvas profiler for your project before optimizations.


With enabled UI:

TODO: It appears that it is necessary to consider the issue of baking text into a texture, if it isn’t changed for a long period of time. Because, black means that the pixel has been overdrawn at least 9 times.


Hi @queriel,

Many thanks for sharing, that is super useful to debug performance. Unreal engine offers an easy to use overdraw visual debugger that I used to find so handy.

Thanks again!

And here is a test on my vegetation full / prone to overdraw scene (Solar Island). We ended up using real meshes for grass/flowers to avoid exactly that, insane overdraw when using billboards.

1 Like

Have you tried using the DrawSorter component from the repo to change the render order in a World layer? How does it look?

OFFTOP: how do you add pcui? Is it loaded as an external script?

This is awesome, I might try to add this to my devtools if I can find an easy way to add it: yaustar.github.io/playcanvas-devtools at master · yaustar/yaustar.github.io · GitHub

If you are using the Editor, you can create a UMD build and add it as normal code file. eg https://playcanvas.com/project/1021958/overview/pcui-30-debug-draw

PCUI build steps here: pcui/BUILDGUIDE.md at main · playcanvas/pcui · GitHub

1 Like

So that’s a very interesting approach! Visually there is almost no change on my test scene, it works as expected, just a slight change on the grass at a distance.

Still I think on my scene I get the best performance with the default preset Material/Mesh on the World layer.

I will make sure to let you know if I test some more, many thanks for sharing this!

Maybe even a depth pre-pass, at least for some nearby meshes, could be beneficial in general. Not that we have some easy way to test it.

It would be cool!

Ofc. It depends on CPU/GPU consumption. So, Material/Mesh is CPU-friendly, Front-To-Back is GPU-friendly. Probably, CPU is a bottleneck for your scene.

Hm. Can we use the occlusion queries (WebGL2) from previous frames for a sorting strategy? The sorting could be performed by considering the fragment count for each MeshInstance, incorporating randomness to account for any variations due to draw order. The heuristic in this case can also improve depth pre-pass for occluding objects. I’m not sure that it works.

Somehow this one doesn’t work with 1.65.3 version.

Do you have an error to share?

It looks like there is a new stencil state control mechanism. I’ll look at it today. UPD: the issue is bigger than I thought.

Fixed. You can use overdraw.js for Playcanvas +1.63 and overdraw_pre_1.62.js for Playcanvas 1.62.


@queriel Thanks…I will try it soon. ~~~~