Jump to content

Pixel-perfect click with atlas animation?


joshrmt
 Share

Recommended Posts

I am trying to get pixel-perfect input clicking with an atlas animation that is using trim.  Whenever I attempt this, the animation does not seem to be hoverable.  I do not see any Phaser Examples which use a texture atlas animation and pixel perfect click detection.  Is there a way I can do this?

 

Also, when I attempt to render the sprite bounds or corners, it doesn't seem to be working.  Could it be that im loading my atlas/animation incorrectly?  The animation itself seems to play properly.

Link to comment
Share on other sites

You are probably in Phaser.AUTO (or WEBGL) mode re: the render bounds/corners, they only render in Canvas mode.

 

There appears to be an issue with trimmed atlases and pixel detection, yes, un-trimmed ones work fine. I'm not sure what you mean by 'positioning issues' though, I use trimmed atlases extensively in all our games (just not with pixel picking ;)) without any positioning issues, so you'll need to provide sample code / images to explain that further really.

Link to comment
Share on other sites

Yeah, I removed the trim from the atlases until this gets fixed.  Any ETA on all that?

 

As for positioning, I believe the trimmed atlas images are not positioned properly if anchors are used.  Since ive switched all my graphics, I don't have a way to play around with it further.  I definitely need to use trimming in the future because the atlas files are entirely too large without it, and will not run on mobile browsers.

 

Also, I noticed that with antialiasing / webgl, the image in the atlas sometimes seems to bleed onto other frames because the atlas itself seems to be anti-aliased rather than the actual cropped image from the atlas.

Link to comment
Share on other sites

Like I said I used trimmed atlases for everything, but I rarely use pixel-perfect hit tests because it's pretty expensive on mobile (constantly getting / writing / reading from image data). But it will be fixed for the next update, keep a watch on the github repo dev branch to see when.

 

The anti-alias factor in WebGL doesn't touch images, just the way graphics primitives are drawn. If you're seeing the edges of frames within trimmed sprites you need to add some shape padding in whatever tool you're making the atlases in. Texture Packer has Border padding and Shape padding (and inner padding) specifically for this. There's a good reason these are set to 2 by default, i.e. it's a very common problem caused by the way the GPU resizes the texture in memory (regardless if it uses mipmapping, liner interpolation, nearest pixel, etc). That's why for example you maybe witness it on Safari on OS X but not on Chrome on Windows, with the exact same texture atlas.

Link to comment
Share on other sites

re: positioning, again anchors are used everywhere in my games, so you'll definitely need to provide a singled out test case for that if you want it looked at further. Note that anchor is for adjusting the way the texture data is rendered, you can also use Sprite.pivot.x/y to adjust placement and rotation.

Link to comment
Share on other sites

Thanks for the help, ill make the padding adjustments accordingly.  I understand the performance implications of the pixel-perfect precision.  I may be able to offer some strategies to improve the performance for this.  One thing ive done in the past is convert the image data to rectangles based on the opaque pixels.

 

As you already know, context.getImageData is an expensive operation, and it is also a costly operation memory-wise based on the dimensions of the image.  Although I do not know the best algorithm to generate the opaque image data, I am confident that you can cache a much cheaper representation of the transparent/opaque pixels.  I will see if I can write up an example this week from some of my older code.

Link to comment
Share on other sites

I did think about something along those lines, basically blocking out large areas of the image that would always fail a pixel check so didn't need to be tested, but as it stands right now all it really does is copy a 1x1 pixel chunk from the source image to the hit test canvas and then get the image data on that. So it's pretty bloody fast because it's the most minimal amount of copy/put/get you can do. Even so, skipping having to do that altogether would be even faster.

 

As they say, the most optimised code is the code that never has to run.

Link to comment
Share on other sites

Rich, regardless of whether you grab a single pixel using getImageData, the browser will still re-allocate the memory for the entire image.  This can become extremely memory intensive, which tends to damage the performance if you are calling getImageData on atlases.  In general, getImageData feels way too expensive for mouse pixel testing on any image larger than 256x256.  Most image atlases are around 1024x1024, so the operation becomes exponentially more expensive.  Couple this with the fact that you may need to do getImageData calls every 'frame', and it suddenly starts to consume some serious resources.

Link to comment
Share on other sites

It creates a buffer the size of the rect you request. WebKit certainly does anyway:

 

https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/platform/graphics/ImageBuffer.cpp&q=getImageData&sq=package:chromium&dr=C&l=358

 

Although that did make me think that 'intensely' searched Sprites could have the option to be "cached", i.e. create a typed array for it that is searched for pixel hits every update, rather than doing any get/put of image data at all. Would be blazingly fast (at least in browsers that support Typed Arrays) but at the cost of memory.

Link to comment
Share on other sites

Hmm, I believe Firefox buffers the entire image, Chrome may be more efficient.  I was using getImageData for hit testing extensively a few months ago, and the results were less than satisfactory, even for the desktop.  I will see if I can do some tests again soon and see if things have improved much.  Since the mouse is used in my game, the hit testing often needs to occur every frame, and could involve multiple sprites.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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