Similar to https://github.com/pixijs/pixi.js/issues/2302, the getCanvas on a RenderTexture does not appear to handle the alpha calculations correctly.
Step 1: Load an image that relies on an alpha channel.
Step 2: Call hue(1) on the ColorMatrixFilter and apply that ColorMatrixFilter.
Step 3: Render the texture, using generateTexture.
Step 4: Call getCanvas() on the generated texture.
This should result in a slight change to the hue, barely noticable.
Instead, the color is heavily distorted.
http://codepen.io/bringerofbabies/pen/yJbGdY
(this uses the newest PixiJS as of today)
This seems to actually be a problem with getCanvas() on a RenderTexture: http://codepen.io/bringerofbabies/pen/yJbGdY
I would guess due to some sort of premultiplied alpha/non-premultiplied alpha mismatch.
Alright - nice catch. I'll adjust the title, so it's easier to find.
I also adjusted the issue text, and linked your codepen, because it gets straight to the point.
I've got a similar problem with the get canvas on a sprite with a custom texture. It seems that came from the getCanvas of the RenderTexture.
http://codepen.io/anon/pen/xEkWRK
Here's a pen I did when trying to figure out this issue, this one uses Graphics instead of Sprite
+1
Oh, that old thing. Thanks to @setpixel we have an answer:
Everything that is rendered in pixi has premultiplied alpha. There's no way to get non-premultiplied info, unless you patch all the object renderers.
To compare the effort, look at #4033, the PR that introduced non-premultiplied alpha in source textures. For NPM targets you'll need even more code.
Thus, canvas() result is correct only if alpha=1 everywhere. Otherwise, you have to take pixels() and divide result by alpha. Should we add special flag in canvas() that allows to do it automatically?
Nice, I applied #4632 and passed the premultiply param as true to solve my old codepen.
var canvas = renderer.extract.canvas(stagingContainer, null, true);
Proof that it works:
https://codepen.io/anon/pen/GQWYZK
Can resurrect my old project now :D
I'm suffering this issue. My app is a drawing app ala procreate with smart brushes, etc... because I use complex textures (brushes) I moved from canvas to pixi webglrenderer for performance. Howevwe I have discoverered that every image save->load degradates the alpha making it darker, almost black. To me the save operation base64 image looks nice. It degradates on every:
class Layer extends PIXI.Sprite
{
constructor(opts)
{
super( PIXI.RenderTexture.create(opts.texture.width, opts.texture.height) );
RENDERER.render(new PIXI.Sprite(opts.texture), this.texture, false, null, false);
this.opts = opts;
this.name = opts.name;
this.history = new History();
}
toBase64()
{
return RENDERER.extract.canvas(this).toDataURL();
}
}
Layer is like a photoshop layer. It's a RenderTexture that renders a given texture that its loaded as a resource saved as base64. Every load makes the image look worse.
Is there any way I can avoid premultiplied? I have changed the renderer canvas method as in #4632 but it does not solve my problem.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.