Skip to content

v5 Hacks

Ivan Popelyshev edited this page Oct 17, 2021 · 29 revisions

Overview

There are cases that cannot be solved with PixiJS API's directly.

Wait, if we already have one demo, why cant just add the code it to pixi vanilla? The problem is that all those solutions are limited and we cant guarantee that they work in general cases. For some of them we cant even produce documentation because it takes time to explain all the tricks.

Many of those cases exists in limbo for years state because there is not enough input from community to make stable APIs and docs.

Nobody is at fault, its just PixiJS team is small and front of works is very big. If you produce modifications of any demos, please submit them to us through issues or at forums, we'll add it in the list and one day small collection of hacks will be reborn as a feature!

Please look in Gotchas too.

PIXI.Transform

Ignore parent scale & rotation

Its possible to ignore parts of parent transform, if you know how Matrices work. Method also works in v4 (with TransformStatic).

https://www.pixiplayground.com/#/edit/qjI_XLeNbxnRmI~2Mndwg

One of users provided alternative implementation with more features: https://github.com/pixijs/pixi.js/issues/6393

PIXI.Sprite

Pixel-Perfect interaction

PixiJS cannot detect pixels with alpha=0, so we have to take it in our hands.

First demo allows to generate hitmap, 1 bits per pixel of baseTexture, and use it for perfect mouseover.

Second demo stores all the colors, 4 bytes per pixel, and allows to detect colors, it returns an array of 4 elements, [R,G,B,A], which are converted to hex tint for sample square.

PIXI.Graphics

Removing 65k vertices limitation

Regarding issues #6047 , #5973 and many others. If you put too many lines and shapes to graphics, output may look wrong. Here's workaround:

https://www.pixiplayground.com/#/edit/NGOapxXGbS5btz5KS7Dge

Execute this if graphics was changed before the render.

graphics.finishPoly(); // in case you didnt use closed paths
graphics.geometry.updateBatches();
// try commenting that to see Uint16 overflow
graphics.geometry._indexBuffer.update(new Uint32Array(graphics.geometry.indices));

Alternatively: patch this line, use Uint32Array https://github.com/pixijs/pixi.js/blob/dev/packages/graphics/src/GraphicsGeometry.js#L554

Its dangerous zone, because some devices browsers dosn't support webgl2 or OES_element_index_uint, and you cant't use Uint32Array there. Currently Webgl2 disabled for all non-apple mobiles, and you must force it via PIXI.settings.PREFER_ENV = PIXI.PIXI.ENV.WEBGL2

UPDATE: This has been fixed in #6417, will be released in 5.3.0.

How to write custom blending

Single color blending

Easy version, if you want to blend a container with certain color: https://www.pixiplayground.com/#/edit/N2y7nxvANk0ibz8vwXVmU

You might want to change how it handles alpha, preserve source alpha as an example.

Cb stands for "color of backdrop", target color. Cs stands for "color of source" , bunny texture.

Formulae is taken from css blending documentation, https://www.w3.org/TR/compositing-1/#blendingoverlay

Blending filters

Using pixi-picture its possible to emulate blending modes using extra backdrop input for a filter. You have to specify shader parts for that.

Filters

Re-use previous frame of filtered object

This hack gives you ability to re-use previous frame of filter to produce new frame, for example as a alpha trail: https://www.pixiplayground.com/#/edit/WHVpFCdiTiTe70dJvahf8

It doesn't belong to a plugin yet.

Shaders

ES3

es3 shader language for webgl2 is supported only if you specify #versioο»Ώn 300 es in the beginning of shader code.

That wont work:

const frag = `
#versioο»Ώn 300 es
...
`;

That should work:

const frag = `#versioο»Ώn 300 es
...
`;

Place in PixiJS source code where that workaround is introduced: https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/shader/Program.js#L53

ShaderToy buffers

Port of example with buffers: https://www.pixiplayground.com/#/edit/iITifzG1lQqrpvf5wQfGK is port of https://www.shadertoy.com/view/ld3GWS

Derivatives:

Here is example that works in both webgl1 & webgl2: https://www.pixiplayground.com/#/edit/W4xeiP6POKeb66ENULseB

If you want make it easier, just use PIXI.PREFER_ENV = PIXI.ENV.WEBGL1 , that way you can omit many IF's

Extract

In general, for any case that is not working, we recommend to switch to renderTexture form of Extract:

const renderTexture = PIXI.RenderTexture.create({width:1, height:1}); // enter your size , maybe from app.screen
renderer.render(container, renderTexture);
const pixels = renderer.extract.pixels (renderTexture);
renderTexture.destroy();

That will ensure there's no problem with bounds or repositioning of container (detach from parent issue).

FilterArea

PixiJS extract example https://pixijs.io/examples/#/demos-advanced/screenshot.js cannot be combined with filter examples easily: extract does use bounds, but if you use filters and filterArea - it will not enlarge the resulting area of screenshot to hold your filter output.

The answer is here: https://github.com/pixijs/pixi.js/issues/6498#issuecomment-604397290 - use renderTexture approach or switch to mesh-shader instead of filter.

Interaction

Prevent pinch gesture in Chrome

Related to https://github.com/pixijs/pixi.js/issues/6414

For preventing page zoom you should prevent wheel event:

window.addEventListener('wheel', e=>{
    e.preventDefault();
}, {passive: false});

Demo: https://www.pixiplayground.com/#/edit/qjyV1YQMdfWc-db8AVGd2

Masked elements dont work

If you use Container as a mask, you have to override that container containsPoint method because we dont have implementation of interaction for container mask yet: https://github.com/pixijs/pixi.js/issues/6509

WebGL2 features

Texture formats

You can use different texture formats by making your own resource, based on BufferResource code: https://github.com/pixijs/pixi.js/issues/6436

Clone this wiki locally