Jump to content

Pixi-canvas: pixi in a context 2d API


Recommended Posts

Hello everyone, 

I'm working on a little project that I named Pixi-Canvas. The idea is to wrap the Pixi renderer in an API that's similar to the 2d canvas API. This allows you to use functions such as context.drawImage, context.fillRect, context.save, context.rotate etc. like you would with canvas.getContext("2d")!  If you're already using Pixi or Phaser, then obviously this is not useful to you. The project is very similar to webgl-2d (if anyone remembers that), except this uses Pixi as the underlying renderer.

You can find this and more info here https://github.com/LuckyKat/pixi-canvas. Please check it out!

While Pixi is the best and fastest renderer out there, I found that Pixi introduces a lot of structures that forces you to work in a certain way. I feel like it's half a game engine already! For my own game engine, I wanted to introduce my own entity-component system, parent-child relations and get in between the render calls per sprite. I felt that Pixi makes that pretty difficult! Working with the 2d canvas API in that sense is much easier, so I wrote a wrapper that could draw pixi sprites like you call context.drawImage. I decided to share this method and write a library that's easy to use.

Performance / difference with Pixi
Using Pixi-Canvas will definitely be slower than using Pixi normally. To test and compare the performance, I replicated the Pixi bunnymark.
On my Surface Pro 4 i5, the amount of bunnies I could spawn before hitting 30 fps:

Canvas 2d: ~4000 bunnies
Pixi-Canvas: ~30.000 bunnies
Pixi: ~55.000 bunnies

Note that this seems to differ a lot per device! I tried this on a Mac Mini the other day and Pixi-Canvas performance was a mere 5000 bunnies. So please give this a try on your own computer and let me know what your performance is. For comparison's sake, I copied Pixi's original bunnymark and turned off the ParticleContainer. ParticleContainers are much faster, but very limited in functionality, so it would be an unfair comparison. I uploaded the bunnymarks here (If anyone from goodboydigital is not ok with this, let me know and I'll take it down):
Pixi-Canvas: http://www.heigames.com/html5/bunnymark
Pixi original without particlecontainers: http://www.heigames.com/html5/pixibunnymark

I've tried to make Pixi-Canvas as optimal as possible of course. Under the hood, it does not use Pixi as you would normally. I'd love to know any tips that could make Pixi-Canvas faster!

Link to comment
Share on other sites

PIXI can be separated to multiple layers:

1. Scene graph: DisplayObject/Container/Sprite

2. Renderer plugins: Sprite Renderer, Graphics Renderer

3. Renderer itself: WebGLRenderer, CanvasRenderer 

4. Texture storage: Texture/BaseTexture

5. Loaders

6. Low-level webgle for pixiv4: pixi-gl-core

I understand why do you want to get rid of (1) and wrap calls of (2) , but you are also wrapping (3), which is very bad. You just have to create your own renderers instead of (2) that accept the same parameters as context2d. BaseTexture optimization is basic thing, and within your approach its impossible to use spritesheets.

Link to comment
Share on other sites

Slotted it into one of my games that uses 2 canvases layered on top of each other.... and..... everything pretty much worked!!! Which was a massive pleasure, since last time i tried that old webgl-2d project, it drew my game into a small corner of the window! Will investigate more for to see if there are actual performance benefits for the variety of devices I have to develop for.

The only place it didn't work correctly is when dealing with globalAlpha I believe. The sprite class I use does a ctx.save(), changes globalAlpha, draws the image, then does a ctx.restore(). With pixi-canvas, as more and more faded images are drawn the globalAlpha decreases further and further towards 0, until the game is fully transparent!

Link to comment
Share on other sites

1 hour ago, HernanZh said:

I think you're misunderstanding, I'm replicating the context 2d API. So in this case: https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage

drawImage take a HTML Image as first parameter and then you pass other coordinates to this. Abstraction is a job for whatever game engine you use, not the renderer!

Replicating is pointless, unless you add some extra features to it. I think I'll make my own canvas2d API imitation that can be used at the same time as PIXI scene graph.

Link to comment
Share on other sites

  • 7 months later...
  • 4 weeks later...

I did something not so different a while back, you might want to take a lok at: https://github.com/karellodewijk/canvas-webgl.

It's an implementation of the canvas2D API in webgl. I got pretty good compatibility with the canvas2D api, I certainly got a lot closer than webgl-2D ever did. I'd say it will mostly work as a canvas2D replacement.

I did run into issues while trying to get any kind of performance out of it. Basically I ran into two issues.

For webgl to be fast you need to batch as many operations as you can into a single draw call. I was sort of trying in the end to delay actually drawing anything until the next animation frame, but it's not so easy. Canvas applications often change the transform or clipping planes, etc, so you have a choice of dealing with all of that in the shader, which gets complex really quickly or sending a draw call every time it happens, which tanks performance. I didn't end up committing my progress here as it broke a lot of the compatibility.

Another issue I ran into is that I ended with some pretty cpu intensive algorithms, especially the polyline algorith/line tesselation, which I wrote. And the triangulation algorithm, which I borrowed. Maybe with webgl2, when geometry shaders are a thing you can offload that to the gpu, but writing it in javascript is never going to be great imo.

Anyway it was interesting to work on.

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.

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.


  • Recently Browsing   0 members

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