# pixi-projection
**Repository Path**: mirrors_pixijs/pixi-projection
## Basic Information
- **Project Name**: pixi-projection
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-08-19
- **Last Updated**: 2026-05-02
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# pixi-projection
[](https://badge.fury.io/js/pixi-projection)
Collection of projections, both 2d and 3d.
To-do:
- Docs
- Graphics support
## Compatibility
Works with PixiJS v6. Compatibility with v5 is not guaranteed.
For v4 please see [v4.x branch](https://github.com/pixijs/pixi-projection/tree/v4.x), npm version `0.2.8`
For v5.1 please use npm version `0.3.5`
For >= v5.2 please see [v5.x branch](https://github.com/pixijs/pixi-projection/tree/v5.x), npm version `0.3.15`
For >= v6 please see [v6.x branch](https://github.com/pixijs/pixi-projection/tree/v6.x), npm version `0.4.3`
It even works with CanvasRenderer, though results can be strange.
## Examples
3d Projection (Yummy!)
[Cards](http://pixijs.github.io/examples/#/plugin-projection/cards.js)
[Runner](http://pixijs.github.io/examples/#/plugin-projection/runner.js)
Projective sprites: Container2d, Sprite2d, Text2d
[Two-point projection](http://pixijs.github.io/examples/#/plugin-projection/basic.js)
[One-point with return to affine](http://pixijs.github.io/examples/#/plugin-projection/plane.js)
[Projective transform of quad](http://pixijs.github.io/examples/#/plugin-projection/quad-homo.js)
## Bilinear projection
There are many ways to define projections even when we use only 2 dimensions.
Surface sprites: Container2s, Sprite2s, Text2s for now only bilinear.
[Bilinear transform of quad](http://pixijs.github.io/examples/#/plugin-projection/quad-bi.js)
## Usage
### Special classes
For every projective way, there are corresponding classes:
* Container2d, Sprite2d, Text2d, TilingSprite2d, Mesh2d, Spine2d
* Sprite3d, Text3d, Mesh3d2d, Spine3d, Camera3d
* Container2s, Sprite2s **WORK IN PROGRESS*
We dont support Graphics yet :(
### Conversion of regular pixi objects
Bear in mind that if you dont use at least one class from `pixi-projection`, it might be tree-shaken away.
Here's how to use regular pixi projects to `3d` projection:
```js
import {Sprite, Container} from 'pixi.js';
var sprite = new Sprite();
sprite.convertTo3d();
sprite.position3d.set(0, 0, 1); //available now!
var container = new Container();
container.convertTo3d();
sprite.position3d.set(0, 0, 1); //available now!
```
You can also convert whole subtree:
```js
import {Container} from 'pixi.js';
var tree = new Container();
var child = new Container();
tree.addChild(child);
tree.convertSubtreeTo2d(tree);
child.position3d.set(0, 0, 1); //available now!
```
(`2d` projection in this example)
### 3D transforms
The most useful thing is 3D transforms.
It all starts from a camera, dont use 3d elements outside of it - it doesn't make sense.
You can create several cameras if you want each element to have its own perspective parameters.
```js
import {Camera3d} from 'pixi-projection';
var camera = new Camera3d();
camera.setPlanes(400, 10, 10000, false); // true if you want orthographics projection
// I assume you have an app or renderer already
camera.position.set(app.screen.width / 2, app.screen.height / 2);
```
In this case, 400 is focus distance. If the width of the screen is 800, that means 90 degrees horizontal FOV.
Everything that's behind `z < -390` will be cut by near plane, everything that's too far away `z > 9600` will be cut too.
We position the camera at the center of the screen, so an element with `position3d=(0,0,0)` will appear right in the center.
However, the camera can look at something else - a character, or just the point with same coords as center of the screen.
```js
camera.position3d.set(app.screen.width/2, app.screen.height/2);
```
With this snippet, every element in the camera that does not use extra 3d fields (`z`, `euler`) will appear exactly like in pixi stage.
That's how awesome our Camera implementation is!
Camera transform differs from other elements:
```js
//camera follows player
camera.position3d.copy(player.position3d);
// player is two times smaller now
player.scale3d.set(0.5);
// but camera follows it too, now everything except player is two times bigger on screen :)
camera.scale3d.set(0.5);
```
Containers and Sprites have extra fields for positioning inside 3d space.
PixiJS gives only `position`, `scale`, `rotation`, `pivot`,
and projection plugin adds `position3d`, `euler`, `scale3d`, `pivot3d`. Those fields applied in transforms after vanilla pixi fields.
The only exception is a `Camera3d`, that applies `projection` just after pixi fields, and then applies 3d fields in **reversed** order.
That's why it can follow elements - its transform negates the element transform.
### Spine
You can apply mixin from `@pixi-spine/projection` to force spine objects to spawn 2d or 3d instances of sprites and meshes.
```js
import {applySpine3dMixin} from 'pixi-projection';
import {SpineBase} from '@pixi-spine/base';
applySpine3dMixin(SpineBase.prototype);
// now all spine instances can be put in 3d projective space
```
If you apply only mixin for `2d`, dont expect fields like `position3d` to be accessible.
If your spine instance always exists in screen spcae, you can use it as it is, like in [Runner example](http://pixijs.github.io/examples/#/plugin-projection/runner.js)
Typing are injected in `SpineBase` class of `@pixi-spine/base` package. This package is usually tree-shaken away, hope its not a problem to see it in your `node_modules` even if you dont use spine.
For UMD version, you should use
```js
PIXI.projection.applySpine3dMixin(PIXI.spine.Spine.prototype);
```
### Heaven
No, we dont support `pixi-heaven` sprites yet.
### What if element is not supported by library?
For complex objects that are not supported by library, there is a way to add them inside the camera **If their plane is perpendicular to the camera**.
Create `Container3d` that returns all children to 2d space: `container3d.affine = PIXI.projection.AFFINE.AXIS_X;`
Any 2d elements added to that container will think of it as a simple 2d container, and custom renderers will work with it just fine.
This way is also **more performant** because **Sprite works faster than Sprite3d. 4x4 matrices ARE VERY SLOW**.
### Sorting
`pixi-projection` provides extra fields to handle sorting.
* `getDepth` returns the distance from near plane to the object local (0,0,0), you can pass it to zIndex or zOrder as `element.zIndex = -element.getDepth()`
* `isFrontFace` detects the face of the object plane
Those fields can be used with custom sorting solution or with [pixi-layers](https://github.com/pixijs/pixi-display/tree/layers/)
### Culling
Will be available after we add it to `@pixi/layers`
## Vanilla JS, UMD build
All pixiJS v6 plugins has special `umd` build suited for vanilla.
Navigate `pixi-projection` npm package, take `dist/pixi-projection.umd.js` file.
```html
```
all classes can be accessed through `PIXI.projection` package.
## Building
You will need to have [node][node] setup on your machine.
Then you can install dependencies and build:
```bash
npm i
npm run build
```
That will output the built distributables to `./dist`.
[node]: https://nodejs.org/
[typescript]: https://www.typescriptlang.org/