Jump to content

Palette Filter


seppuku
 Share

Recommended Posts

Hi,

I'm trying to render palette-based graphics with PIXI. I've been having some success, but with a very hackish solution.

What I got as input is a bitmap with 0-255 value indexes to a palette which is another vector containing RGB 0-255 values.

I'm currently creating a texture for the base image, storing the palette index in the alpha channel and leaving the other channels blank. This is directly added to the sprite. On top, I hacked one of the existing filter into behaving like a palette filter (see attached file). The filter receives as parameter another texture, which is the palette itself. **I'm using the term "hacked" because I have practically no experience with WebGL.

The base image is fairly static, while the palette can change regularly (unit remapping, lighting etc).

My current solution is to get that bitmap data onto a canvas then create a texture from that and attach it to the sprite. Another texture is created in the same manner for the palette and assigned to the PaletteFilter. The palette filter is added to the filters property of the sprite and that's it.

Now, the questions:
- is there a way I could create a texture directly from a typed array instead of having to create a canvas every time? And maybe being able to update it directly instead of replacing it every time with another texture?
- could I do the same for the filter and somehow get a typed array to the shader instead of constructing a texture?
- can I create an alpha gl texture instead of the RGB one? Will there be any performance improvements for not using those extra empty channels?

Also, one problem I'm having are memory leaks. It seems that textures that I'm creating with 'fromCanvas' are never trashed, even if I call destroy(true). I even added the patch from the dev branch (which I saw in a reported issue), but it's the same.

Only solution I found was to do a PIXI.BaseTextureCache = {} every time I regenerated the textures.


Any advice?
Thanks

PaletteFilter.txt

Link to comment
Share on other sites

I created a pallete filter for palette swapping a while ago that worked out pretty well, maybe it will help you a bit:

 

https://github.com/GoodBoyDigital/pixi.js/blob/palette-swap-filter/src/pixi/filters/PaletteFilter.js

 

Basically I would apply this filter to a sprite that looks like this:

 

indexed.png

 

Passing in a texture for a pallete that looked like this:

 

palette.png

And the shader would output this:

 

enemies.gif

 

Basically you could just swap the palette texture uniform and it changes the sprite output. I also created a tool to generate the palette and indexed image from a normal image (attached). You can open that file in your browser, then drag/drop any image and it will split it out for you (uses File API so open it locally in Chrome).

 

As far as your specific questions:

 

is there a way I could create a texture directly from a typed array instead of having to create a canvas every time? And maybe being able to update it directly instead of replacing it every time with another texture?

 

We don't have a "data texture" like three.js, sounds like a good candidate for a PR :D

 

could I do the same for the filter and somehow get a typed array to the shader instead of constructing a texture?

 

See above, likely what we would need is a "data texture" where the base texture source is just a Uint8Array that can be loaded directly. Here is where the texture is loaded into webgl, there would need to be logic here to handle that type of texture.

 

can I create an alpha gl texture instead of the RGB one? Will there be any performance improvements for not using those extra empty channels?

 

Be careful here, browsers a lot of times will treat alpha pixels differently by removing RGB info when there is no opacity. There isn't really any performance difference in using one channel or another for indexing.

 

It seems that textures that I'm creating with 'fromCanvas' are never trashed, even if I call destroy(true)

 

This is a known issue, and is being worked on. See pixi.js issue #671.

paletter.html

Link to comment
Share on other sites

Thank you for the detailed reply. I appreciate it :D

 

Regarding the data texture, I will probably fiddle some more with it this weekend and see what I can do. I need to better understand the source code, first, before making any pull requests :)

 

I didn't know about the thing with the alpha channel. It probably works in my case since the first color is always transparent so it doesn't affect the image in any way.

Link to comment
Share on other sites

  • 1 year later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...