1
\$\begingroup\$

I am trying to draw thousands of lines between nodes, and the line positions are constantly changing (i.e. consider a node being dragged while connected to thousands of children by these lines).

Below is a simplified example of an issue I have. When drawing several thousands of lines in WebGL or Canvas, the rendering takes a long time (up to a second or more). For each line that needs to be updated, I clear the PIXI.Graphics object and then redraw it from scratch.

I was wondering if there is a way to improve this by batching the draw to WebGL somehow. Ideally the render time could be reduced significantly, so I could draw up to 100,000 lines in less than a second.

Warning: It may crash your browser tab - lower the number of objects to below 20,000 if this happens.

var container = new PIXI.Container(),
    i,
    renderer = PIXI.autoDetectRenderer(1000, 1000);
renderer.backgroundColor = 0xFFFFFF;
document.body.appendChild(renderer.view);
for (i = 0; i < 20000; i++) {
    line = new PIXI.Graphics();
    line.lineStyle(1, 0x888888, 1);
    line.moveTo(0,0);
    line.lineTo(10*i,1000);
    container.addChild(line);
}
renderer.render(container);
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.8/pixi.js"></script>

Pure JavaScript/WebGL/Canvas improvements are useful as well (Pixi is not required).

\$\endgroup\$
  • \$\begingroup\$ There's no good way now. Pixi only support continued lines. like: lineTo(x,y); lineTo(x2,y2); .... And moveTo will make a new graphicData. And I don't see any code about merge lines graphicData. @ratchet freak, If you're right, please show me the PIXI's merge line segments code. \$\endgroup\$ – Master K Oct 31 '17 at 12:23
3
\$\begingroup\$

As a first step instead of 20k graphics objects containing each a single line use a single graphics object and put the 20k lines in it

var container = new PIXI.Container(),
    i,
    renderer = PIXI.autoDetectRenderer(1000, 1000);
renderer.backgroundColor = 0xFFFFFF;
document.body.appendChild(renderer.view);

line = new PIXI.Graphics();
line.lineStyle(1, 0x888888, 1);
for (i = 0; i < 5000; i++) {
    line.moveTo(0,0);
    line.lineTo(10*i,1000);
}
container.addChild(line);

renderer.render(container);
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/3.0.8/pixi.js"></script>

PIXI will then batch all those lines into a single buffer and draw it using a single draw Elements command.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I thought about this approach earlier this morning as well but didn't realize how significant the benefit would be. I didn't realize PIXI controlled the buffer per PIXI.Graphics object (still very new to the library). \$\endgroup\$ – grovesNL Nov 9 '15 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.