Jump to content

Performance Drop with beginFill on Mouse Move


daviddarx
 Share

Recommended Posts

Hi everybody, 

I am starting with Pixisjs and getting a small performance issue with something that should be really simple to process: 
when I draw a triangle (moveTo, lineTo) on each mousemove event with one of the points which is the mouse position, it performs well at the beginning, but the more i follow on with mouse move, the worse get the performance. After a minute, the FPS ist really low. 

I made a pen to illustrate it:
https://codepen.io/daviddarx/pen/MLEbvE

If I clear the graphic at the beginning of each mouse move event (//graphics.clear();), the performance stays good all the time. 
But unfortunately, it given't the effect that I will reach anymore :( . 

Am I missing something? Should I try another approach to draw elements on the stage on high frequency without erasing the stage first?

Thank you a lot for your support!
David
 
 

Link to comment
Share on other sites

That's a complex question regarding Graphics internals, and how webGLData is formed based on graphics: https://github.com/pixijs/pixi.js/blob/v4.x/src/core/graphics/webgl/GraphicsRenderer.js#L73

I do not know whether its algorithm failing at your case or you add so much data that any algo will fail. Maybe algorithm does not use multiple buffers and uses only one which gets reuploaded on every new triangle, in that case yeah , its supposed to be slow.

I hope you have enough knowledge of chunked algorithms ( like stuff separated into several parts)  to determine whether its pixi failing on your own, I just dont want to spend my time remembering that part of algo. In that case you can create multiple Graphics instead, and filll only latest one, while other stay static.

Yes, some drawing apps draw only new elements on stage. Some are drawing only changed chunks of bitmap data, and remember them in temporary RenderTextures. Its a very big topic that takes a day to explain.

One of those drawing apps: https://github.com/wonderunit/alchemancy , sorry for difficult filter stuff (positioning is weird, yeah), but we dont have better open-source example than this one.

Link to comment
Share on other sites

Hi @ivan.popelyshev

Thank you for your quick answer! 

Hum, I unfortunately don't understand a lot of what you're telling :'( . 

Actually, the only part I understand is: "In that case you can create multiple Graphics instead, and filll only latest one, while other stay static.". 
Should I try with 2 graphics? One for drawing the new triangle with graphics.clears(), and one in background with the result copied there at the beginning of each frame? Did I understand good? 

And one last question: if y do the same with native js/canvas, without pixijs, should it perform better? 


Thank you a lot for your help!
David

 

Link to comment
Share on other sites

What you could do is draw the triangles into a texture and then display that texture on the stage. That way you wouldn't have a very large graphics object redrawn every time.

So something like this:

 

//Pseudo code. Might have some syntax errors.
var texture = PIXI.RenderTexture.create( app.screen.width, app.screen.height);
var graphics = new PIXI.Graphics();

var sprite = new Sprite(texture);
app.stage.addChild(sprite);

//Draw other shapes you want here to graphics and then draw that to texture also.
graphics.beginFill()
...
graphics.endFIll();
app.renderer.render(graphics, texture);

function mouseMoveHandler()
{
	graphics.clear();
	graphics.beginFill(0x000000);
	graphics.lineStyle(Math.random()*3, 0xffffff, 1);

	// draw a shape
	graphics.moveTo(0,0);
	graphics.lineTo(250, 0);
	graphics.lineTo(event.pageX, event.pageY);
	graphics.lineTo(0, 250);
	graphics.endFill();
	
	app.renderer.render( graphics, texture, false);
}

 

Link to comment
Share on other sites

Your problem would be the same with any other technology, Sprite2D, Flash, etc ... Would slow down the exact same way. You cannot just keep on drawing new objects (triangle) constantly, it's too much work for the CPU or the GPU or both. The solution > You need to cache. The basic idea: Draw what's NEW with a graphic but draw what's already DRAWN in a texture, you end up with a texture with everything that has already been drawn (a piece of cake for GPU to render) and a graphic with only the latest stokes (expensive but manageable by GPU). When user draws again render your texture (draw cache) with everything the user has done, empty your graphic and start drawing again with it, etc ....

Link to comment
Share on other sites

Hi guys!
 

@Exca Thank you for the solution, it works perfekt!! Alelujah!

@ivan.popelyshev Thank you for the small correction ?

@botmaster Thank you very much for the explication of the solution. I am a complete newby and thought that the caching happens per default, that if I don't clear the graphic it would stays in cache and the only thing that would then happen is the small drawing on the picture which ist already drawn. No I understand it the the graphic not a bitmap is, but an object with all instances "living" there. It will help me further a lot, thank you! 

The only problem that I now have is: the aliasing doens't work anymore: 

https://codepen.io/daviddarx/pen/MLEbvE

I searched in the documentation of RenderTexture and Sprite, no antialiasing options there. 
I tried to replace app.renderer.render(graphics, texture, false) with app.renderer.render(graphics, texture, true), but it doens't work neither. 

Do you have any idea where the problem could come from? 
Thank you a lot!
David

 

 

Link to comment
Share on other sites

it wont work on RenderTexture, its just not possible in webgl1. But you can try to switch pixi default "app.render()" that is registered in "app.ticker" that way it doesnt clear old framebuffer, but that wont work good on some devices, and workaround includes BLENDMODE.NONE from pixi-v5.. yeah its not pretty :)

Want pretty things - learn how webgl works and make your changes to pixi.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...