v5 Migration Guide
This document is useful for developers who are attempting to upgrading from v4 to v5. This includes gotchas and important context for understanding why your v4 code made need some subtle changes. In general, we've try to be as backward-compatible in v5 with the use of deprecation warnings in the console
. There are, however, sometimes when changes are too substantial and require some additional help.
🚧 API Changes
Making WebGL First-Class
PixiJS v5 has made WebGL the first-class renderer and made CanvasRenderer to be second-class. Functionally, there's not much that changed from v4, but there are a bunch of subtle internal naming changes which could trip-up some developers upgrading to v5. For instance:
WebGLRenderer
becomesRenderer
renderWebGL
becomesrender
(in DisplayObject, Sprite, Container, etc)_renderWebGL
becomes_render
(in DisplayObject, Container, etc)
If you created a plugin or project that previously used render
on a Container (see #5510), this will probably cause your project to not render correctly. Please consider renaming your user-defined render
to something else. In most other cases, you'll get a deprecation warning trying to invoke WebGL-related classes or methods, e.g., new PIXI.WebGLRenderer()
.
Renderer Parameters
Specifying options
as a third parameter in Renderer
constructor is officially dropped (same with PIXI.Application
, PIXI.autoDetectRenderer
& PIXI.CanvasRenderer
). In v4 we supported two function signatures, but in v5 we dropped width, height, options
signature. Please add width
and height
to options
.
const renderer = new PIXI.Renderer(800, 600, { transparent: true }); // bad
const renderer = new PIXI.Renderer({ width: 800, height: 600, transparent: true }); // good
Note: Adding
transparent: true
in Renderer or Application constructor options might help with strange artifacts on some devices, but it might reduce FPS. It's much better thanpreserveDrawingBuffer: true
.If you need the v4 default behavior of resizing the canvas using css pixels, add
autoDensity: true
to the options.
Not everything went to params. To enable WebGL1 even if WebGL2 is available, use
PIXI.settings.PREFER_ENV = PIXI.ENV.WEBGL;
Mesh, Plane, Rope
PixiJS v5 introduces a new class called PIXI.Mesh
. This allows overriding the default shader and the ability to add more attributes to geometry. For example, you can add colors to vertices.
The old v4 Mesh class has moved from PIXI.mesh.Mesh
to PIXI.SimpleMesh
, it extends PIXI.Mesh
.
PIXI.mesh.Rope
, PIXI.mesh.Plane
, PIXI.mesh.NineSlicePlane
have moved to PIXI.SimpleRope
, PIXI.SimplePlane
and PIXI.NineSlicePlane
respectively.
If you used custom shaders or generated meshes in v4, you might be impacted by these changes in v5.
PIXI.SimpleMesh
fields vertices
, uvs
, indices
are wrapped inside mesh.geometry
attribute buffers. For example, this is how access to buffers provided through mesh.uvBuffer
property:
get uvBuffer()
{
return this.geometry.buffers[1];
}
The indices
property shortcut is also missing, but you can access the data inside mesh.geometry.indexBuffer
.
You can override buffer data, and notify it that data was changed, in this case buffer will be uploaded to GPU lazily. Previously in v4 mesh had several flags that indicated which attributes have to be updated and their names confused people.
Graphics Holes
Drawing holes in Graphics was very limited in v4. This only supported non-Shape drawing, like using lineTo
, bezierCurveTo
, etc. In v5, we improved the hole API by supporting shapes. Unfortunately, there's no deprecation strategy to support the v4 API. For instance, in v4:
const graphic = new PIXI.Graphics()
.beginFill(0xff0000)
.moveTo(0, 0)
.lineTo(100, 0)
.lineTo(100, 100)
.lineTo(0, 100)
.moveTo(10, 10)
.lineTo(90, 10)
.lineTo(90, 90)
.lineTo(10, 90)
.addHole();
In v5, Graphics has simplified and the API changed from addHole
to beginHole
and endHole
.
const graphic = new PIXI.Graphics()
.beginFill(0xff0000)
.drawRect(0, 0, 100, 100)
.beginHole()
.drawCircle(50, 50, 30)
.endHole();
Filter Padding
In v4 filters had a default padding of 4
and in v5 this has been changed to a default of 0
. This can cause some filters to look broken when used. To fix this issue simply add some padding to the filters you create.
// Glow filter from https://github.com/pixijs/pixi-filters
const filter = new PIXI.filters.GlowFilter();
filter.padding = 4;
Some filters, like BlurFilter
, automatically calculate the padding so changes may not be necessary.
Filter Default Vertex Shader
We reorganized all uniforms dedicated to coordinate system transforms, and renamed them. If your filter doesn't work anymore, check if you use default vertex shader. In that case, you can use old v4 vertex shader code.
All changes are explained in [[Creating Filters|v5-Creating-filters]]
Enable Mipmapping for RenderTexture
Previously, you may have ended up with code like this in v4 (specifically if you saw Ivan's comment/JSFiddle):
const renderer = PIXI.autoDetectRenderer();
renderer.bindTexture(baseRenderTex, false, 0);
const glTex = baseRenderTex._glTextures[renderer.CONTEXT_UID];
glTex.enableMipmap(); // this is what actually generates mipmaps in WebGL
glTex.enableLinearScaling(); // this is what tells WebGL to USE those mipmaps
In v5, this code is no longer needed.
BaseTexture Resources
One of the newest features in v5 is that we decoupled all the asset-specific functionality from BaseTexture. We created a new system called "resources" and each BaseTexture now has a resource that wraps some specific asset type. For instance: VideoResource, SVGResource, ImageResource, CanvasResource. In the future, we hope to be able to add other resource types. If there were asset-specific methods or properties being called before, these will probably be on baseTexture.resource
.
Also, we removed all of the from*
methods from BaseTexture, so you just can call BaseTexture.from
and pass in whatever resource. Please see docs for more information about from
.
const canvas = document.createElement('canvas');
const baseTexture = PIXI.BaseTexture.from(canvas);
That API also allows to use pure WebGL and 2d context calls, see the gradient example.
BaseTexture.source
Has been moved to baseTexture.resource.source
, moved into resource corresponding to the baseTexture. baseTexture.resource
does not exist for RenderTexture, and source does not exist for resources that dont have source.
Graphics Interaction
If you use transparent interactive graphics trick, make sure that you use specify alpha=0 for all element, not for its parts. How PixiJS deals with shapes that have alpha=0 is considered undefined behaviour. We might change it back, but we have no guarantees about it.
graphics.beginFill(0xffffff, 0.0); //bad
graphics.alpha = 0; //good
📦 Publishing Changes
Canvas Becomes Legacy
Since WebGL and WebGL2 are now first-class, we have removed the canvas-based fallback from the default pixi.js package. If you need CanvasRenderer
, you should switch to use pixi.js-legacy instead.
import * as PIXI from "pixi.js";
// Will NOT return CanvasRenderer because canvas-based
// functionality was removed from "pixi.js"
const renderer = PIXI.autoDetectRenderer(); // return PIXI.Renderer or throws error
Instead, use the legacy bundle to have access to the canvas rendering.
import * as PIXI from "pixi.js-legacy";
const renderer = PIXI.autoDetectRenderer(); // returns PIXI.Renderer or PIXI.CanvasRenderer
Bundling Changes
If you're using Rollup, Parcel or another bundler to add PixiJS into your project there are a few subtle changes when moving to v5. Namely, the global PIXI
object is no longer created automatically. This was removed from bundling for two purpose: 1) to improve tree-shaking for bundlers, and 2) for security purpose by protecting PIXI
.
This is no longer a valid way to import:
import "pixi.js";
const renderer = PIXI.autoDetectRenderer(); // INVALID! No more global.PIXI!
Instead, you should import as a namespace or individual elements:
import * as PIXI from "pixi.js";
const renderer = PIXI.autoDetectRenderer();
// or even better:
import { autoDetectRenderer } from "pixi.js";
const renderer = autoDetectRenderer();
Lastly, some 3rd-party plugins maybe expecting window.PIXI
, so you might have to explicitly expose the global like this, however this is not recommended.
import * as PIXI from 'pixi.js';
window.PIXI = PIXI; // some bundlers might prefer "global" instead of "window"
Webpack
When Webpack and 3rd-party plugins, like pixi-spine, you might have difficulties building the global PIXI
object resulting in a runtime error ReferenceError: PIXI is not defined
. Usually this can be resolved by using Webpack shimming globals.
For instance, here's your import code:
import * as PIXI from 'pixi.js';
import 'pixi-spine'; // or other plugins that need global 'PIXI' to be defined first
Add a plugins
section to your webpack.config.js to let know Webpack that the global PIXI
variable make reference to pixi.js
module. For instance:
const webpack = require('webpack');
module.exports = {
entry: '...',
output: {
...
},
plugins: [
new webpack.ProvidePlugin({
PIXI: 'pixi.js'
})
]
}