Jump to content

CanvasRenderer performance


Bobby
 Share

Recommended Posts

I made a little demo called pixi-bouncing-box. You can see the demo here. So initially there are 10 bouncing boxes. When button add 10 boxes is clicked, another 10 boxes are added to stage. The animation run smoothly at 60fps, even after 90 boxes added.

 

But after awhile, the fps gradually decreased from 60 to 50 then down until 20fps with 90 boxes added to stage. I saw the PIXI v3 100k bunnies benchmark and it claimed it got 40fps. Did I make some mistakes? The code I made is available at Github, but I'll also post it here in case you need a quick scan.

;(function ( window, document, undefined ) {    'use strict';    var WIN_WIDTH   = window.innerWidth;    var WIN_HEIGHT  = window.innerHeight;    var btnAdd = document.querySelector('#add');    var renderer = new PIXI.CanvasRenderer(WIN_WIDTH, WIN_HEIGHT, {        transparent: false,        autoResize: true    });    renderer.backgroundColor = 0xF5866B;    document.body.appendChild( renderer.view );    var stage = new PIXI.Container();    var speed = 10;    var box_w = 70;    var box_h = 70;    var boxes = [];    addTenBoxes();    btnAdd.addEventListener('click', addTenBoxes, false);    var boxEdgeRight    = WIN_WIDTH - box_w;    var boxEdgeBottom   = WIN_HEIGHT - box_h;    requestAnimationFrame(animate);    function animate() {        for (var i = boxes.length - 1; i >= 0; i--) {            var curr = boxes[i];                        if ( curr.isGoingRight ) {                curr.position.x += speed;            } else {                curr.position.x -= speed;            }            if ( curr.isGoingDown ) {                curr.position.y += speed;            } else {                curr.position.y -= speed;            }            if ( curr.position.y < 0 ) {                curr.isGoingDown = true;                changeBoxColor( curr );            }            if ( curr.position.x < 0 ) {                curr.isGoingRight = true;                changeBoxColor( curr );            }            if ( curr.position.y > boxEdgeBottom ) {                curr.isGoingDown = false;                changeBoxColor( curr );            }            if ( curr.position.x > boxEdgeRight ) {                curr.isGoingRight = false;                changeBoxColor( curr );            }        }        renderer.render(stage);        requestAnimationFrame(animate);    }    function addTenBoxes() {        for (var i = 10 - 1; i >= 0; i--) {            var box = new PIXI.Graphics();            box.beginFill(getRandomColor());            box.drawRect(0,0,box_w,box_h);            box.isGoingRight    = true;            box.isGoingDown     = true;            box.position.x      = getRandomXPos();            box.position.y      = getRandomYPos();            box.endFill();            stage.addChild(box);            boxes.push(box);        }    }    function changeBoxColor( _box ) {        _box.beginFill( randomColor().replace('#', '0x') );        _box.drawRect(0,0,box_w,box_h);        _box.endFill();    }    function getRandomXPos() {        return Math.random() * WIN_WIDTH - box_w;    }    function getRandomYPos() {        return Math.random() * WIN_HEIGHT - box_h;    }    function getRandomColor() {        return randomColor().replace('#', '0x');    }})( window, document );

Does this have something to do with CanvasRenderer? Because when I switch to WebGLRenderer, the animation run smoothly at 60fps even after 3-5 minutes. I am aware that WebGLRenderer is faster than CanvasRenderer but not all device support it, that's why I used CanvasRenderer.

 

This demo is tested in the latest Chrome on Yosemite.

Link to comment
Share on other sites

There is a big difference in perf (on canvas) between Graphics and Sprites. A sprite is a single call to "drawImage", a Graphics object is multiple calls to setup the canvas for a draw and then a draw of each shape. There is also the fact that you have multiple Graphics objects, which is rarely necessary.

 

The biggest thing you can do to improve is to use a single Graphics object with reduces the number of transforms that have to be done to the canvas:

var boxes = new PIXI.Graphics();stage.addChild(boxes);function addTenBoxes() {    for (var i = 10 - 1; i >= 0; i--) {        box.beginFill(getRandomColor());        box.drawRect(getRandomXPos(), getRandomYPos(), box_w, box_h);        box.isGoingRight    = true;        box.isGoingDown     = true;        box.endFill();    }}
Link to comment
Share on other sites

Using single Graphics object can't achieve the same result I expected. Anyway I found the culprit that make fps gradually drop, it was the changeBoxColor function.

            if ( curr.position.y < 0 ) {                curr.isGoingDown = true;                changeBoxColor( curr ); // Taking much resource            }            if ( curr.position.x < 0 ) {                curr.isGoingRight = true;                changeBoxColor( curr ); // Taking much resource            }            if ( curr.position.y > boxEdgeBottom ) {                curr.isGoingDown = false;                changeBoxColor( curr ); // Taking much resource            }            if ( curr.position.x > boxEdgeRight ) {                curr.isGoingRight = false;                changeBoxColor( curr ); // Taking much resource            }

in the end, I drop that feature and boom! the animation is now running smoothly with 100 boxes.

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...