v8.0.0-beta.0
Pre-releaseπ¨ WARNING π¨
These beta releases are still subject to API changes
π NEW π
New Package Structure
-
No more "lerna," PixiJS is now just one package with one import root:
import {stuff} from βpixi.jsβ
. This change means we now have much better tree shaking during app compilation, reducing bundle size if not imported.Old:
import { Sprite } from "@pixi/sprite"; import { Graphic } from "@pixi/graphics";
New:
import { Sprite, Graphic } from "pixi.js";
Renderer Initialization Update
-
When initializing a renderer, this process is now asynchronous, serving two purposes:
- Identifying and loading the necessary renderer code (minimizing bundling).
- Allowing asynchronous initialization of webGPU.
-
We are using dynamic imports to correctly load the necessary renderer code, meaning you should only be loading the code you need!
import { Application, autoDetectRenderer } from "pixi.js"; const app = new Application(); (async () => { await app.init({ // application options }); // or const renderer = await autoDetectRenderer({}); // WebGL or WebGPU // do pixi things })();
WebGPU Renderer & New Architecture
- PixiJS now supports rendering using the WebGPU API. It gracefully falls back to the WebGL renderer if WebGPU is not available.
- RenderPipes:
- The renderer now uses a pipeline system to render objects. This allows for more flexibility and extensibility.
- This means that render logic is no longer within the Item (e.g., Sprite); it now relies on the renderer to handle changes in data.
- Pixi can render in two modes:
- 'Fast mode' when the scene structure remains unchanged between frames.
- 'Regular mode' for scenes that change.
- Scene changes include:
- Adding or removing a child element.
- Changing element visibility.
- Swapping a texture or blendMode on a batched element.
- Rebuilding a Graphics/Mesh that has been batched.
- Regular mode is as fast as or faster than v7's rendering methods in many cases.
- Pixi also now reactively renders the scene
- Only updates the transform of elements that have changed.
- The changes to the renderer have allowed us to make some significant performance improvements:
- In 'Fast' mode, v8 achieves up to 200% higher FPS than v7 in Chrome Canary.
- In 'Regular' mode, v8 achieves up to 50% higher FPS in Chrome Canary.
- We have also added a shader compiler that lets us build shaders lego style by stacking shader bits together to change functionality. This will give us a platform to take shaders to the next level.
DisplayObject Overhaul
DisplayObject
has been removed and replaced withContainer
.Container
now accepts aview
that allows it to render something to the screen. This wonβt affect you as we still haveSprite
, βMeshβ etc. Its just a little more organised under the hood- From v8, only
Container
's are allowed to have children. This means you can no longer dosprite.addChild(child)
. Instead you must docontainer.addChild(sprite, child)
.const wrapper = new Container(); const sprite = new Sprite(); const child = new Sprite(); wrapper.addChild(sprite, child);
- Layers:
Container
now has alayer
property. This allows you to group objects together and move them around without the cost of transforming the scene graph. - Blend modes are now inherited from the parent container.
- Tint is also inherited, allowing tinting of all children in a container.
- We have also added support for a wide range of Photoshop-like filters, including Vivid Light, Color Burn, and more.
- Bounds now calculated without affecting scene graph transforms
Texture Overhaul
- Textures have been completely rewritten and contain a lot less code than before. This has made it much easier for us to maintain compared to v7.
- A Texture now consist of
TextureSource
,TextureStyle
, andTextureLayout
- Added
antialias
option to all textures
Graphics Overhaul
- Graphics API has been changed to make it more intuitive and easier to use.
graphics .rect(50, 50, 100, 100) .fill(0xde3249);
- We added a
GraphicsContext
that powers all graphics now. These contexts can be shared between graphics - Added support for svg drawing
- Added gradient support
- Added
GraphicsPath
's that can be used to draw and share shapes.- also support svg paths! eg
new GraphicsPath('M 100 350 q 150 -300 300 0')
- also support svg paths! eg
- You can now build a geometry from a path using
buildGeometryFromPath(path)
- Dynamic graphics are much faster: up to 60% faster.
Text Overhaul
- Text has been completely rewritten and now uses a single class. You specify the rendering mode in the constructor
new Text({ text: "hello", renderMode: "canvas" }); new Text({ text: "hello", renderMode: "bitmap" }); new Text({ text: "hello", renderMode: "html" });
- Dynamic bitmap fonts will generate glyphs on the fly, so no need to build the font first
- bitmap font and canvas fonts layout almost identically now - so switching is much more trivial
- text style supports the same fill style as graphics objects
- bitmap text is now measured more efficiently
- HTML text will now handle font loading the same way you load any other kind of font with Assets. No need to load these fonts in separately anymore
Other Changes
- Options for all! We have tried to standardize all constructors of PixiJS objects using a single options param. This is great as it means we can easily add props in the future, and also unlocks the ability to mix object parameters.
π₯ Breaking Changes π₯
Below is a non complete list of breaking changes. This will be updated fully before the official release
Application
-
PixiJS will now need to be initialised asynchronously. With the introduction of the WebGPU renderer PixiJS will now need to be awaited before being used
Old:import { Application } from "pixi.js"; const app = new Application(); // do pixi things
New:
import { Application } from "pixi.js"; const app = new Application(); (async () => { await app.init({ // application options }); // do pixi things })();
-
view
renamed tocanvas
Old:const app = new Application(); document.body.appendChild(app.view);
New:
const app = new Application({ canvas: myCanvas }); await app.init(); document.body.appendChild(app.canvas);
Renderer
-
Renderer.render()
now takes an object if passing multiple arguments
Old:renderer.render(stage); renderer.render(stage, renderTexture);
New:
renderer.render(stage); renderer.render({ stage, renderTexture });
-
Renderer
class no longer exists. Replaced withWebGLRenderer
&WebGPURenderer
.Renderer
as a type still exists
Old:const renderer = new Renderer();
New:
const renderer = new WebGLRenderer(); const renderer = new WebGPURenderer(); // or const renderer = autoDetectRenderer(); // WebGL or WebGPU
Scene
-
Only
Container
's are allowed to have children
Old:const sprite = new Sprite(); const child = new Sprite(); sprite.addChild(child);
New:
const wrapper = new Container(); const sprite = new Sprite(); const child = new Sprite(); wrapper.addChild(sprite, child);
-
Text
is now one unified class. You specify the rendering mode in the constructor
Old:new Text("hello"); new BitmapText("hello"); new HTMLText("hello");
New:
new Text({ text: "hello", renderMode: "canvas" }); new Text({ text: "hello", renderMode: "bitmap" }); new Text({ text: "hello", renderMode: "html" });
-
Text.dropShadow
is now an object
Old:text.dropShadow = true; text.dropShadowAlpha = 1; text.dropShadowAngle = Math.PI / 6; text.dropShadowBlur = 0; text.dropShadowColor = "black"; text.dropShadowDistance = 5;
New:
text.dropShadow = { alpha: 1, angle: Math.PI / 6, blur: 0, color: "black", distance: 5, };
-
Text.stroke
is now an object
Old:text.stroke = "black"; text.strokeThickness = 0;
New:
text.stroke = { color: "black", width: 2, };
-
NineSlicePlane
renamed toNineSliceSprite
and options converted to an object
Old:new NineSlicePlane(texture, 10, 10, 10, 10);
New:
new NineSliceSprite({ texture, leftWidth: 10, rightWidth: 10, topHeight: 10, bottomHeight: 10, });
-
MeshGeometry
&PlaneGeometry
options converted to an object
Old:new PlaneGeometry(100, 100, 10, 10); new MeshGeometry(vertices, uvs, indices);
New:
new PlaneGeometry({ width: 100, height: 100, verticesX: 10, verticesY: 10, }); new MeshGeometry({ positions: vertices, uvs, indices, });
-
Mesh
options converted to an object
Old:new Mesh(geometry, shader, state, drawMode);
New:
// `drawMode` is now `geometry.topology` geometry.topology = "triangle-strip"; new Mesh({ geometry, shader });
-
Mesh.material
has been removed useMesh.shader
instead
Graphics
- You no longer need to begin/end fills, you just draw the shape and fill it in one go.
Old:
graphics
.beginFill(0xDE3249)
.drawRect(50, 50, 100, 100);
.endFill();
New:
graphics
.rect(50, 50, 100, 100)
.fill(0xde3249);
- Other API changes
graphics.drawCircle() -> graphics.circle()
graphics.drawEllipse() -> graphics.ellipse()
graphics.drawPolygon() -> graphics.polygon()
graphics.drawRect() -> graphics.rect()
graphics.drawRoundedRect() -> graphics.roundRect()
graphics.drawStar() -> graphics.star()
Misc
-
A
Ticker
instance is now passed to the callback
Old:Ticker.shared.add((dt) => { bunny.rotation += dt; });
New:
Ticker.shared.add((ticker) => { bunny.rotation += ticker.deltaTime; });
-
enums have been removed in favour of string literals
Old:container.blendMode = BLEND_MODES.ADD; baseTexture.wrapMode = WRAP_MODES.CLAMP; baseTexture.scaleMode = SCALE_MODES.NEAREST;
New:
container.blendMode = "add"; texture.source.wrapMode = "clamp"; texture.source.scaleMode = "nearest";