Giter Site home page Giter Site logo

pixi-heaven's Introduction

pixi-heaven

Build npm version

This is heaven for sprites. Want to color them better? Wanna use advanced colors? Its all here!

Works with PixiJS v7

For v6 please see v6.x branch, npm version 0.3.3

For v5 please see v5.x branch, npm version 0.2.3

For v4 please see v4.x branch, npm version 0.1.21

Examples

Done:

  • Advanced color modes
  • Polygon packing
  • Mesh with trimmed textures

Migration

To use es6 modules in IDE, its better to have distinct class names. That's why PIXI.heaven.Sprite is now SpriteH, same with SimpleMeshH and BitmapTextH

How to use

Just add pixi-heaven.js file in your build.

import { SpriteH } from 'pixi-heaven';

var sprite = new SpriteH();
// good old sprite tint
sprite.color.setLight(0.5, 1.0, 0.5);

// dark tint - new feature
sprite.color.setDark(0.2, 0.2, 0.2);

// change single component, useful for tweening
sprite.color.darkG = 0.1;

Or convert PIXI sprite. In that case, make sure that you actually use heaven Sprite somewhere, or it'll be tree-shaken away.

import { Sprite } from 'pixi.js';

var sprite = new Sprite(someTexture);

// pixi vanilla way, optional
sprite.tint = 0x80ff80;

// activate the plugin!
sprite.convertToHeaven();

Useful example: invert the colors

sprite.color.setLight(0, 0, 0);
sprite.color.setDark(1, 1, 1);

Make whole sprite of one color:

sprite.tint = 0xffaacc;
sprite.color.dark[0] = sprite.color.light[0];
sprite.color.dark[1] = sprite.color.light[1];
sprite.color.dark[2] = sprite.color.light[2];
//dont forget to invalidate, after you changed dark DIRECTLY
sprite.color.invalidate();

Meshes

Heaven meshes SimpleMeshH can be used with trimmed textures.

Unfortunately, meshes cant be converted, you have to create mesh instead of PIXI.SimpleMesh

That adds extra shader switched, and disables batching, but it shows correct result!

To switch it off, set

import {settings, CLAMP_OPTIONS} from 'pixi-heaven';
// Default, PixiJS vanilla mode
settings.MESH_CLAMP = heaven.CLAMP_OPTIONS.NEVER;

To always use the trimmed texture shader, set

import {settings, CLAMP_OPTIONS} from 'pixi-heaven';
// Default, PixiJS vanilla mode
settings.MESH_CLAMP = CLAMP_OPTIONS.ALWAYS;

Mesh batching works the same way as in pixi.

PIXI.Mesh.BATCHABLE_SIZE = 1000; // bigger meshes now are batched too!
PIXI.Mesh.BATCHABLE_SIZE = 1; // or not.

How to use with spine

This plugin enables light-dark tint of spine >= 3.6.

Mixin can be applied to any spine prototype class: SpineBase, Spine or your own extended class. Usually its applied to SpineBase.

Light-dark tint works like in sprites.

import {SpineBase} from '@pixi-spine/base';
import {applySpineMixin} from 'pixi-heaven';

applySpineMixin(SpineBase.prototype);

spine = new Spine();
spine.color.setLight(0.5, 1.0, 0.5);
spine.color.setDark(0.2, 0.2, 0.2);

batch ADD blending mode with NORMAL

This feature comes from unity spine runtime - ADD can be emulated by NORMAL with zero tint alpha. It reduces number of batches and drawcalls.

import {settings} from 'pixi-heaven';
settings.BLEND_ADD_UNITY = true;

Animation

Thanks to @finscn, unlike pixiJS vanilla AnimatedSprite, here animation is a component:

import {AnimationState} from 'pixi-heaven';

new AnimationState(frames).bind(sprite);
sprite.animState.gotoAndStop(2);

It still uses PIXI.Ticker.shared if you dont specify autoUpdate=false. It will be stopped and destroyed with the bound element.

How to mask sprites with sprites

Plugin adds special renderer that has faster masks than just sprite.mask. It also works on heaven meshes.

import {SpriteH} from 'pixi-heaven';

sprite = new SpriteH();
sprite.maskSprite = sprite2; //set it
sprite.pluginName = 'batchMasked'; //enable special plugin rendering
sprite2.renderable = false; //turn off rendering

Batching works with spine, just enable maskSprite in any sprite or mesh of spine instance, all pluginName's will be adjusted automagically.

Look at Spine file to see how it actually works.

Vanilla JS, UMD build

All pixiJS v6 plugins has special umd build suited for vanilla. Navigate pixi-heaven npm package, take dist/pixi-heaven.umd.js file.

<script src='lib/pixi.js'></script>
<script src='lib/pixi-heaven.umd.js'></script>

all classes can be accessed through PIXI.heaven package.

Building

You will need to have node setup on your machine.

Then you can install dependencies and build:

npm i
npm run build

That will output the built distributables to ./dist.

pixi-heaven's People

Contributors

exponenta avatar ivanpopelyshev avatar lucidolab avatar shadowlauch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pixi-heaven's Issues

Tint a Spine slot

Would it be possible to add the possibility to tint a Spine slot? Tinting an entire Spine object with heaven works fine, but I cannot tint separate slots this way. Tinting a slot the "normal" way works (i.e. with the tint property), but that way I cannot make the entire slot one color (except black ofc).

Masks usage with spine

Hi.
At work we're having performance problems when using multiple pixi masks on mobile.
Pixi-heaven is one of the options we're reviewing as a possible solution to the problem.
We're using PIXI.js version 6.0.4.

After running several tests with the sprite masks which pixi-heaven supports, we saw a performance improvement.
But we also use spine in some projects.
I'm having problems figuring out how sprite masks are used with SpineMesh.
I get a console error.
I even tried to use a sprite with a maskSprite as a container for the spine. But the mask seems to not apply to any of the Spine Mesh children.

Demo:

https://www.pixiplayground.com/#/edit/21YI4PTVR8Qkl9Rk8gQQN

not work on spine

hum, i just apply haven for spine obj, and it look not work.
spine have color property, but it not affect the rendering. ?
It work good on sprite objet only.
???
image

i use the same code as the example.
new PIXI.heaven.spine.Spine(data.spineData);
any idea ?
i also have the last pixi-spine https://github.com/pixijs/pixi-spine/releases.

my order are also correct in my html

    <body style="background-color: black">
        <script type="text/javascript" src="js/libs/iziToast/iziToast.js"></script> <!--iziToast js for editor-->
        <script type="text/javascript" src="js/libs/jscolor/jscolor.min.js"></script><!--colorJs tint for editor-->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/10.0.0/bootstrap-slider.min.js"></script>
        <script type="text/javascript" src="js/libs/pixi.js"></script>
        <script type="text/javascript" src="js/libs/pixi-tilemap.js"></script>
        <script type="text/javascript" src="js/libs/pixi-picture.js"></script>
        <script type="text/javascript" src="js/libs/pixi-layers.js"></script>
        <script type="text/javascript" src="js/libs/pixi-filters.js"></script>
        <script type="text/javascript" src="js/libs/pixi-spine.js"></script>
        <script type="text/javascript" src="js/libs/pixi-heaven.js"></script>

MaskedBatchRenderer requires 'highp' fragment shader precision

Thanks for this repo! I'm having issues where some masked sprites won't render on Android. I narrowed this down to the default PIXI.settings.PRECISION_FRAGMENT value, which is 'mediump' on Android and 'highp' on iOS.

Setting PIXI.settings.PRECISION_FRAGMENT = 'highp' fixes the problem on Android, however I don't like risking crashes on older devices. Or rather re-introducing this render bug as I did notice in the Pixi source code it automatically degrades the precision if it is not available.

I could not wrap my head around the shader code itself, however seeing the arithmetic of determining the texture and mask ids, I tried lowering the MaskedPluginFactory.MAX_TEXTURES to 2, which seems to have fixed the rendering without the shader requiring 'highp' precision.

I was wondering if this 'fix' will sustain on all devices and if it affects batching performance, @ivanpopelyshev ?

Cannot get pixi-heven to work with pixi-spine and webpack

Hi everyone!

I'm having a really hard time getting pixi-heaven to work with my app. I followed instructions for pixi-spine and added the following to my webpack config:

{
  actions.setWebpackConfig({
    plugins: [
      new webpack.ProvidePlugin({
        PIXI: 'pixi.js',
      }),
    ],
  })
}

And these are my imports on the file which uses pixi-heaven and pixi-spine:

import * as PIXI from 'pixi.js'
window.PIXI = PIXI
import 'pixi-spine'
import 'pixi-heaven'

When I do the following:

const sprite = new PIXI.Sprite(PIXI.Texture.WHITE)
sprite.convertToHeaven()
sprite.scale = { x: 15, y: 15 }

I get the following error:

Uncaught TypeError: Cannot read property '0' of null
    at BatchPlugin.packInterleavedGeometry (pixi-heaven.js:916)
    at BatchPlugin../node_modules/@pixi/core/lib/core.es.js.AbstractBatchRenderer.buildDrawCalls (core.es.js:10524)
    at BatchPlugin../node_modules/@pixi/core/lib/core.es.js.AbstractBatchRenderer.buildTexturesAndDrawCalls (core.es.js:10486)
    at BatchPlugin../node_modules/@pixi/core/lib/core.es.js.AbstractBatchRenderer.flush (core.es.js:10600)
    at BatchPlugin../node_modules/@pixi/core/lib/core.es.js.AbstractBatchRenderer.stop (core.es.js:10623)
    at BatchSystem../node_modules/@pixi/core/lib/core.es.js.BatchSystem.setObjectRenderer (core.es.js:4814)
    at SpineSprite../node_modules/@pixi/sprite/lib/sprite.es.js.Sprite._render (sprite.es.js:347)
    at SpineSprite../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1534)
    at Container../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1537)
    at Spine../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1537)
    at Container../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1537)
    at Viewport../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1537)
    at Container../node_modules/@pixi/display/lib/display.es.js.Container.render (display.es.js:1537)
    at Renderer../node_modules/@pixi/core/lib/core.es.js.Renderer.render (core.es.js:9863)
    at Application../node_modules/@pixi/app/lib/app.es.js.Application.render (app.es.js:95)
    at TickerListener../node_modules/@pixi/ticker/lib/ticker.es.js.TickerListener.emit (ticker.es.js:129)
    at Ticker../node_modules/@pixi/ticker/lib/ticker.es.js.Ticker.update (ticker.es.js:584)
    at Ticker._tick (ticker.es.js:334)

If I try the following instead, sprite doesn't render the Sprite and I get no errors.

var sprite = new PIXI.heaven.Sprite(PIXI.Texture.WHITE)
sprite.scale = { x: 15, y: 15 }

To discard the option I'm doing something else incorrectly, I'm trying the same without pixi-heaven and it works fine.

I'm using the latest versions of all the mentioned modules. Any help would be greatly appreciated!

Thanks!
Santiago

proj+heaven bug

Hum cool feature but...
heaven projs

this bug seems to happen in this context:

parentContainer: Container2d
childDiffuse: Sprite2d + spriteHeaven
childNormal: Sprite2d + spriteHeaven

edit:
i mean like this
image

dark tint doesn't work on meshes

We have a spine animation which has some mesh animations with tint black enabled. This doesn't seem to work at all with this latest build

is there any way to apply mask to multiple sprites in a batch operation

I have multiple sprites to apply mask to each. each mask is same in its shape and only its positions is different from each other.

I'm currently using heaven.Sprite.maskSprite and "spriteMasked" plugin to apply mask to sprites and it seems masking for each sprite is done as single operation.

I hope I can apply mask to all those sprites in a single batch operation.
Is there any way that I can achieve this using pixi-heaven?

To help your understanding, these are things that I want to apply mask
image
so there would be a mask applied to each heart.
and currently mask is applied total 5 times, 1 for each heart

I assumed this by inspecting webgl drawing procedure
image
You can see that masking shader is applied 5 times in a single frame.

No dist/ folder

I tired to use the latest version (v0.3.0) but after npm i --save pixi-heaven the dependency folder (inside node_modules/) only contains:

  • global.d.ts
  • index.d.ts
  • LICENSE
  • package.json
  • README.md

There is no dist/ forder nor JS files.

I tried with yarn and different versions of npm.

question: performance

Hi Ivan you mention that this can effect performance. Anything in particular that is really bad?
Have you noticed a performance hit with polygon packing for example?

Thanks

Incorrect rendering of spine mesh + blend additive, using pixi-heaven

There is some issue with rendering mesh sprite along with blend mode additive on it (that's the best conclusion I can give at the moment). Please see attached video - you can see spine animation played there with and without heaven plugin being enabled.

pixi-heaven-issue-2021-03-02_16.16.35.mp4

Affected spine asset: Aliens.zip
Spine viewer used to demo the issue: https://d2yxcxpiisr7s0.cloudfront.net/
Feel free to check it yourself, just drag&drop zip with spine over the spine-viewer app.

Package versions affected by the issue (currently used in spine viewer):

"pixi-heaven": "0.2.2"
"pixi-spine": "2.0.5"
"pixi.js": "5.3.7"

Using pixi V4 with spine and heaven didn't produce mentioned issues, packages below:

"pixi-heaven": "0.1.21"
"pixi-spine": "1.5.22"
"pixi.js": "4.8.9"

Is there any way to apply masking as a batch operation to multiple sprites?

I have multiple sprites to apply mask to each. each mask is same in its shape and only its positions is different from each other.

I'm currently using heaven.Sprite.maskSprite and "spriteMasked" plugin to apply mask to sprites and it seems masking for each sprite is done as single operation.

I hope I can apply mask to all those sprites in a single batch operation.
Is there any way that I can achieve this using pixi-heaven?

To help your understanding, these are things that I want to apply mask
image
so there would be a mask applied to each heart.
and currently mask is applied total 5 times, 1 for each heart

I assumed this by inspecting webgl drawing procedure
image
You can see that masking shader is applied 5 times in a single frame.

sprite.color.alpha ?

what are suppose do the alpha?
I trying to change the value but its not work !, It alway 1.
Should allowed and able to change this value?
Now I make slider, it really more easy for control coloration in pixi-haven with high precision.
image

maskSprite emits GL ERROR when applied

I'm trying to convert masking as batch operation using pixi-heaven.

But below code which is almost same as that of in README, emits error
[.WebGL-0x7f87e084c200]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0

        this.heartGauge.maskSprite = this.mask;
        this.heartGauge.pluginName = 'spriteMasked';
        this.mask.renderable = false;

        this.container.addChild(
            this.heartGauge,
            this.frame,
            this.mask
        );

heartGauge is a PIXI.heaven.Sprite and mask is a PIXI.Sprite.

container is plain Pixi container

Plain PIXI mask works well with same mask texture.

My pixi version is v4.

Is there anything I'm missing?

Simple Rope support

Hello,

will be there support for SimpleRope in v5?
Im asking because of trimmed textures used in Pixi.SimpleRope.

Thank you.

Failed to Server Render (SSR)

Pixi.js works great in SSR environments like Gatsby.

But as soon as I add import { SpriteH } from 'pixi-heaven to my project SSR breaks with the following error, and I can't seem to get around it even though the line of code I have that uses SpriteH is not called on the server side. I assume the library initializes immediately prior to my code execution.

I'd like to use pixi-heaven for the performance benefits of alpha sprite masking.

Failed to Server Render (SSR)
Error message:
ReferenceError: document is not defined

File:
node_modules/@pixi/settings/lib/adapter.mjs:3:1

Stack:
WebpackError: ReferenceError: document is not defined
    at artshop-ai/node_modules/@pixi/settings/lib/adapter.mjs:3:1
    at artshop-ai/node_modules/@pixi/core/lib/textures/Texture.mjs:278:22
    at artshop-ai/node_modules/pixi-heaven/lib/twotint/sprites/MaskedBatchRenderer.mjs:5:15
    at artshop-ai/webpack/bootstrap:19:1
    at artshop-ai/webpack/bootstrap:19:1
    at artshop-ai/webpack/bootstrap:19:1
    at artshop-ai/webpack/bootstrap:19:1
    

I also tried dynamic imports but then I get a different problem that likely requires some re-initialization of the pixi library possibly?:

Error in function BatchSystem.setObjectRenderer in ./node_modules/@pixi/core/lib/batch/BatchSystem.mjs:16
Cannot read properties of undefined (reading 'start')

./node_modules/@pixi/core/lib/batch/BatchSystem.mjs:16

Importing pixi-heaven

Hey everyone,

Hopefully this is a simple one. I use Next.js and render my PIXI app as a dynamic component.

I'm trying to use pixi-heaven to improve the peformance of masking a video. I installed pixi-heaven via npm (tried copy pasting js as well):

"pixi-heaven": "^0.2.3",
"pixi-spine": "^3.0.4",
"pixi.js": "^6.0.1",

I import it as follows:

import * as PIXI from "pixi.js";
(window as any).PIXI = PIXI;
import "pixi-spine";

And whichever way I try to go (npm and importing the js file) I end up with PIXI is not defined:

ReferenceError: PIXI is not defined
    at eval (pixi-heaven.js?d473:67)
    at eval (pixi-heaven.js?d473:68)
    at Object../node_modules/pixi-heaven/dist/pixi-heaven.js (1.js:11749)
    at __webpack_require__ (webpack.js?ts=1624919291402:873)
    at fn (webpack.js?ts=1624919291402:151)
    at Module.eval (playerBody.ts?7752:1)
    at eval (playerBody.ts?7752:270)
    at Module../components/gamev2/bodies/playerBody.ts (1.js:71)
    at __webpack_require__ (webpack.js?ts=1624919291402:873)
    at fn (webpack.js?ts=1624919291402:151)
    at Module.eval (PlayerController.ts:7)
    at eval (PlayerController.ts?f800:398)
    at Module../components/gamev2/controllers/PlayerController.ts (1.js:143)
    at __webpack_require__ (webpack.js?ts=1624919291402:873)
    at fn (webpack.js?ts=1624919291402:151)
    at Module.eval (game.ts:8)
    at eval (game.ts?5f5f:291)
    at Module../components/gamev2/game.ts (1.js:191)
    at __webpack_require__ (webpack.js?ts=1624919291402:873)
    at fn (webpack.js?ts=1624919291402:151)
    at Module.eval (newGame.tsx:15)
    at eval (newGame.tsx?72c9:427)
    at Module../components/gamev2/newGame.tsx (1.js:203)
    at __webpack_require__ (webpack.js?ts=1624919291402:873)
    at fn (webpack.js?ts=1624919291402:151)

I also tried a voodoo solution of trying to import the ts files straight into the codebase but unfortunately with a plethora of errors.

Could anyone please advise me on how to bring pixi-heaven into the project? I'm hoping I'm doing something silly or basic wrong.

color balancing

hey nice work @ivanpopelyshev .
I have a little trouble to calibrate and working with for the moment.
I experimente.
Is it possible to have a kind of color balance?

sans-titre-1

        // test pixi-heaven ///////////////////// <=
        iziT.jscolorTintDark.onFineChange = function(){
            //objSprite.tint = `0x${this.targetElement.value}`
            objSprite.color.setDark(this.rgb[0]/255,this.rgb[1]/255,this.rgb[2]/255); // rgb
            console.log1('objSprite.color: ', objSprite.color.dark);
        };
        iziT.jscolorTintLight.onFineChange = function(){
            //objSprite.tint = `0x${this.targetElement.value}`
            objSprite.color.setLight(this.rgb[0]/255,this.rgb[1]/255,this.rgb[2]/255); // rgb
            console.log1('objSprite.color: ', objSprite.color.light);
        };

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.