davidfig / pixi-cull

a library to visibly cull objects designed to work with pixi.js
MIT License
112 stars 15 forks source link

Performance degraded with higher number of culled elements #12

Closed markkuhar closed 3 years ago

markkuhar commented 3 years ago

Hi,

when running examples with higher number of culled squares (> 500k) performance drops. Since, with culling, GPU should only render visible elements I am wondering why it comes to these performance drops? Shouldn't performance drops correlate with number of visible elements rather than culled elements? Is this an issue or I am missing something?

Thanks in advance!

Testing code:

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello World</title>
</head>
  <script src="pixi/pixi.min.js"></script>
  <script src="pixi/simple.js"></script>
  <script src="pixi/spatial-hash.js"></script>
  <script src="pixi/viewport.js"></script>
<body>
  <script type="text/javascript">
    var app = new PIXI.Application();
    document.body.appendChild(app.view);

    // create viewport
    var viewport = new Viewport.Viewport({
        screenWidth: app.view.offsetWidth,
        screenHeight: app.view.offsetHeight,
        worldWidth: 10000,
        worldHeight: 10000
    });

    app.stage.addChild(viewport);
    viewport.drag().pinch().wheel().decelerate().moveCenter(5000, 5000);

    // add red boxes
    for (var i = 0; i < 200000; i++)
    {
        var sprite = viewport.addChild(new PIXI.Sprite(PIXI.Texture.WHITE));
        sprite.tint = 0xff0000;
        sprite.width = sprite.height = 20
        sprite.position.set(Math.random() * 100000, Math.random() * 100000);
    }

    var cull = new Simple();
    cull.addList(viewport.children);
    cull.cull(viewport.getVisibleBounds());

    // cull whenever the viewport moves
    PIXI.ticker.shared.add(() =>
    {
        if (viewport.dirty)
        {
            cull.cull(viewport.getVisibleBounds());
            viewport.dirty = false;
            console.log(cull.stats());
        }
    });
  </script>
</body>
</html>
davidfig commented 3 years ago

Have you tried using the SpatialHash culling instead of Simple? The Simple version checks all nodes every frame. Hash breaks them into hashed blocks (think of a large grid where nodes are placed into squares, and the square is invalidated when outside the viewport). so it compares fewer nodes. For larger number of nodes, it might help.

Either way, 500k is a lot of nodes to compare. If you can avoid doing the culling every frame, it would definitely help.

markkuhar commented 3 years ago

Thanks!