devon-o / Starling-Filters

A collection of filters for use with the Starling AS3 framework.
208 stars 52 forks source link

PixelateFilter and clipRect #3

Closed rekomat closed 11 years ago

rekomat commented 11 years ago

Hi Devon

First things first: Your filters really, really rock! Thanks a lot for sharing! :)

I played around with the PixelateFilter and stumbled across a strange behavior: When I use the PixelateFilter in combination with a clipRect, I get a transparent gap on the left/upper side. The size of the gap equals pixelSize set in the filter.

Here's some code to reproduce. It results in a 3 pixel (filter.pixelSize - clipRect.x) gap on the left side.

// clipped sprite 
var box:Sprite = new Sprite();
box.clipRect = new Rectangle(1, 0, 40, 40); // set y to 1 for 'upper gap'
addChild(box);

// adding image to clipped sprite
var img:Image = new Image(myTexture);
img.filter = new PixelateFilter(4);
box.addChild(img);

As I do not have a clue of AGAL, I'm really helpless with this one… Do you have any idea?

Thanks, René

devon-o commented 11 years ago

Hey René,

Thank you for the kind words on the filters. I appreciate it.

Unfortunately, I can't be of much help here other than to try to explain what's happening. The way the pixelate filter works is by sampling the texture at certain coordinates then applying that sample n pixels down and to the right. When a clipping rectangle is applied to the texture with Starling it, in turn, applies a scissors rectangle via the Context3D instance. That scissors rect basically ignores all pixels outside of the rectangle. The shader still samples those ignored pixels though, gets a 'nothing' value and applies that 'nothing' down and to the right as usual producing the gap you're seeing. One possible work around (though it's admittedly not that great) is to set the x and y values of the clipping rectangle to a multiple of the pixel value of the Pixelate Filter (so, in your exampe, if you set the clipping rectangle to (4, 0, 50, 50) or (4, 4, 50, 50) or (4, 8, 50, 50), etc. it would work as there would be a pixel value there to sample).

I did some experimenting hoping that possibly caching the filter before applying the clipping rectangle would do the trick, but no dice.

Since this is really out of my hands, I'm going to close this, but I'm going to play around a bit more and if I find a solution (perhaps rendering the image to a texture then applying the clipping rectangle, but that could be quite an involved process within the Starling framework), I will post back here.

Thanks again, -d.

rekomat commented 11 years ago

Hey Devon!

Thanks a lot for your explanation! I was afraid this could be a hairy one…

Unfortunately setting the x/y properties of the clipping rect to multiples of the pixelSize value does not really work in my case as the image with the filter is draggable by the user and I work with pixelSize value of ~10.

Thus I tried to render the image to a texture which I used to create a new clipped image. But whenever I try to do so, the filter is removed. So I end up with a new texture but without the filter applied to it. argh

I'll keep trying and I would post back here if I can come up with a solution.

Thanks a lot for your help! And of course, any hint is very welcome! :)

Regards, René