PixiJS v5 lands
Can you believe it’s been it’s been this long? Nearly 2 years?? I guess that’s what happens because… life! (for me, I blame the fact I added two kids to the world)
Still, better late than never right? So without further ado... (drum roll)
PixiJS v5 is here!
That’s right, today we get to officially announce that v5 has landed in the PixiJS master branch and also on npm. This is a huge step as it means it’s ready for the world to start using! Excitingly this means the next master release will see v5 land for the masses.
Wipe those tears of joy from your face and continue reading to get the headlines on why v5 is worth paying attention to.
New build and project structure
PixiJS is now made of multiple consumable components that can be installed in your project with NPM/Yarn. These foundational components are designed to work with Webpack/Rollup and other JS packaging systems. They support ES modules for treeshaking. It’s now much easier to exclude modules you don’t need for your project, like Graphics, Interaction, etc.
Also, PixiJS has two high-level bundle packages called pixi.js (WebGL-only) and pixi.js-legacy (roughly equivalent to current pixi.js)
Best of all, this has resulted in a both builds being smaller with pixi.js clocking in at about 20% smaller than v4!
If thats still not small enough for you then you should definitely check out http://pixijs.io/customize/ Matt Karl (@bigtimebuddy) has been hard at work creating a tool that lets you decide which parts of pixi.js you want in you library and then letting the bundlers tree shake unwanted modules away. It’s a simple and effective way to reduce code size by only including the modules you are actually using.
By default, WebGL is now a first-class technology in PixiJS. We have taken context2d rendering (aka CanvasRenderer) and decided that the future of rich rendering on the web is WebGL. Fallback support for context2d is still available by using the pixi.js-legacy bundle. However you’ll noticed that many names have changed internally, for instance, WebGLRender is now Renderer.
New architecture, Same API
All aspects of the renderer have been broken down into discrete systems.
We also support WebGL2 where possible too. As we evolve v5 we plan on making use of some specific WebGL2 features to make PixiJS even faster! (I’m look into at you uniform buffer objects and texture array 2d!)
But cruciality, even though there has been a huge change to the core code base, the API has remained pretty much the same. So switching to v5 will be incredibly easy. For those looking to switch existing projects, check out our handy migration guide here
All together now, Batching for all
You may well know that we’re always banging on about how fast sprites are because they are batched super efficiently. Now in PixiJS v5, sprites graphics and meshes are all batched together. Not gonna lie, my brain melted building this feature, but it has been totally worth it as the performance gains of this for real life PixiJS are pretty big! Check out the demo.
This is huge as it now means graphics are as fast to use as sprites as they now get the same respect. Expect a blog post dedicated to how we achieved this soon, but for now sit back and enjoy faster rendering!
Graphics, plus plus!
The Graphics objects in PixiJS have been given a lot of love for v5. We realised that actually given a few extra abilities Graphics could be used to create super complex static elements that render super fast! Aside from the aforementioned batching, we added:
- You can now do texture fills using beginTextureFill.
- You can now clone and share the geometry with different graphics objects. Sharing a geometry means we don’t have to do all the maths again calculating and tessellating the shape! Simply call graphics.clone() and you get an memory efficient fast copy o fit to reuse.
- beginHole/endHole. Although this existed in v4, it has been recoded so that any shape can be a hole rather than only a polygon. caveats being that the hole must be entirely within the shape, or weird things start happening! (We will fix that soon)
- You can pass a transform to graphics when drawing this means you can scale/rotate a shape as it’s drawn into the graphics object.
This one will get its own blog post too! Check it out here.
So filters have been built again! This time even faster than v4. Great attention has been paid to the number of GPU interactions that were happening. We got these down to the bare minimum with some smart caching. And we all know the golden rule of rendering with WebGL.The less the CPU talks to GPU the faster things are. Like frenemies…
Textures get a refresh
Textures have been given a massive overhaul, getting them ready for maximum flexibility and power. Underneath a baseTexture we have introduced a new concept called resources. This is where the logic for how to parse and upload something to the GPU is kept. We have included new textures types such as:
- TextureArray (WebGL 2 only!)
- BufferTexture (Floating point / Half float / uint32)
You can even create your own resources if you want too. Also we have opened up the options so that you can now set customise the WebGL texture settings in a much easier manner. We have now exposed key properties such as Format, Type and target giving power users much more control.
The coolest thing is that all of the above it optional and is simply there if required. The API for creating textures has become even more simpler with the introduction of smart texture creation.
All textures can now be created using the following lines:
// create a texture
const texture = PIXI.Texture.from('my-amazing-bunny.png');
const videoTexture = PIXI.Texture.from('hilariuos-cat-video.mp4');
const svgTexture = PIXI.Texture.from('complicated.svg');
// the same for sprites:
const sprite = PIXI.Sprite.from('cheese-selection.jpg')
PixiJS will automatically figure out what kind of texture needs to be created. Lovely! This may seem like a small thing but, in practice it’s been really nice to use, it’s the little things in life that count :)
Brand spanking new mid level API
Ok so I saved the best till last as I think this isn’t far the coolest part of v5. The midlevel API. We created an API that basically abstracts as much of WebGL as possible but still keeping all the power, giving you guys the power to create awesome WebGL that is automatically optimised for you!
In fact all of v5 is built on top of this API. Expect a more detailed post and examples for this one soon. Until then, here’s a simple overview of that API.
- This represents all the attribute data for an object being rendered. It can contain whatever you want such as position, UVs, normals etc. Like v4 this class makes use of the vertex array objects to minimise GPU calls.
- The use of caching is used to ensure that geometries that are the same are only uploaded to the GPU once.
- We also infer as much from the shaders as possible. All you need to do is provide in an array for each attribute, PixiJS figures out the rest.
- Cool features include the ability to automatically interleave data into a single buffer for maximum rendering efficiency.
- This represents a WebGL program. They are cached behind the scenes so only one program instance of each type of shader is ever uploaded to the GPU and is shared across all instances of the Shader.
- Setting Uniforms is a simple case of modifying a js object. All syncing is handled behind the scenes. The api also supports the ability to share uniforms values across objects for example camera and perspective transforms via uniform groups.
- Also, the addition of a caching layer means uniforms updates only happen when if they need to. PixiJS actually generates custom upload code specific to each shader to achieve the same performance as if it was hand written yourself!
- This is a construct that stores the state of the WebGL context. For example whether culling is enabled or depth testing is enabled. All possible combinations of the WebGL states are bit packed into a unique integer. This means comparing WebGL states required to render different objects is boiled down to a single integer comparison, so it is super fast. Also, when there is a state change required, only the required states are changed.
Now I know the above examples are not exactly designed to blow your mind, but with this API it makes it super easy to slip from low level to high level graphics coding all in one place.
As a proof of concept we built a 3D engine on top of the API to prove to ourselves it is as flexible as we hoped! Check it out here:
Expect a LOT of examples to come through highlighting how to use all this extra ooommpphh!
A new playground for PixiJS
More to come
Thats quite a lot to take in, but hopefully all these shiny new features will make your PixiJS life a lot easier. More performance and more features, not bad at all!
Massive thanks to the PixiJS team who worked so hard to get this version out of the door. This project truly could not exist without everyone donating their time to make this happen. You guys rock!