Thoughts and Ideas about optimizing 2D Per Pixel Collisions

Started by
9 comments, last by renman29 8 years, 11 months ago

Hello Everyone,

i'm looking for thoughts and ideas about optimizing Per Pixel Collisions with DX 9 for 2D game, the performance now is good but if there are some others things to do in order to optimize it further, then why not?

Currently i have done the following (there is nothing special in the code since its the standard algorithm):

1. Build Bool Collision mask for every frame in Texture Sprite Sheet. so it goes with lockRect , nested loops and get alpha color then populate the mask with 0,1 based on that.

2. Checking normal collisions with Rect Intersection first, if collision detected then perform per pixel collision check based on collisions masks per the

displayed frames. first IntresectRect, if true then check the intersectedRect pixels for source and destination for non alpha pixels colliding.

3. Put a timer to check per pixel collisions if any collision detected for every 2-3 frames instead of every frame since the user will not notice the difference.

Now one of my concerns is loading time when building collisions masks, now it takes less than 1 second to populate a sprite sheet 3200x1600 which is the level's boss, most of other sprite sheets are like 1/4 or 1/3 the size of Boss's sheet, but my CPU is pretty powerful 3770k@ 4.5Ghz and cannot take it as standard.

so what others things i can do to optimize and improve performance for loading and collision further?

Thanks

Advertisement
don't use per-pixel collision. use simple boxes, circles, and convex shapes to approximate your characters. remember your physics world does not need to be a 1:1 representation of your rendered world.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

don't use per-pixel collision. use simple boxes, circles, and convex shapes to approximate your characters. remember your physics world does not need to be a 1:1 representation of your rendered world.

Yes i hear you and this approach is done for enemies since they dont take much space and textures are pretty small on screen so the difference is too narrow, but for the Boss which occupies half of the screen, the transparent area is too big for the player not to notice especially for dynamic game like mine, my game is sandbox not a static game and the player can create his own Enemies, Bosses,.... and import any image he wants, where as it would be much more easier if its static by defining hitboxes for Bosses and just Rect intersection.

Pre-save the collision masks instead of creating them from D3D memory, so they can just be read into an array. Requiring textures to be lockable and readable sounds like a bad idea. Should make loading time pretty close to zero too if you can just read the data from a file already in your internal collision mask format.

don't use per-pixel collision. use simple boxes, circles, and convex shapes to approximate your characters. remember your physics world does not need to be a 1:1 representation of your rendered world.

Yes i hear you and this approach is done for enemies since they dont take much space and textures are pretty small on screen so the difference is too narrow, but for the Boss which occupies half of the screen, the transparent area is too big for the player not to notice especially for dynamic game like mine, my game is sandbox not a static game and the player can create his own Enemies, Bosses,.... and import any image he wants, where as it would be much more easier if its static by defining hitboxes for Bosses and just Rect intersection.

So do what almost every other 2D game does when faced with the same problem - use multiple hitboxes for objects when needed.

This has the added advantage that it makes it easier for different parts to have different collision properties (e.g. this part does more collision damage, this other part blocks projectiless, etc).

don't use per-pixel collision. use simple boxes, circles, and convex shapes to approximate your characters. remember your physics world does not need to be a 1:1 representation of your rendered world.


Yes i hear you and this approach is done for enemies since they dont take much space and textures are pretty small on screen so the difference is too narrow, but for the Boss which occupies half of the screen, the transparent area is too big for the player not to notice especially for dynamic game like mine, my game is sandbox not a static game and the player can create his own Enemies, Bosses,.... and import any image he wants, where as it would be much more easier if its static by defining hitboxes for Bosses and just Rect intersection.

As anthony said, you don't have to use a single hitbox, basically what your doing now is creating a ton of hit boxs in a grid, how many of those hit boxes could be eliminated if you used a larger hitbox to approximate the overall shape, then several smaller ones to handle the sections of the enemy not covered by the large hitbox.?
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

In my experience, per pixel collision is viable for small sprites but at 1600x3200 you're way, way beyond what I would consider.

I'm not quite sure how D3D even takes part in this. I would do it all on CPU (except perhaps the mask generation).

Keep in mind that to get back the results from collision testing those huge masks you force a full CPU/GPU sync. That's like nailing yourself to the floor.

Previously "Krohm"

Thanks guys for your suggestions, Erik suggestion is viable, great and i like the pre-generated mask option which makes loading time near zero, now it takes 1-2 seconds max on my machine but might take alot on other weaker CPUs, so this is great.

However for multiple HitBoxes, its not viable because i feel its too hard for the end user to grasp, i thought of that earlier and to give him a window and he defines hitboxes by drawing Rects marking those areas for the Boss, but if i'm an end user/player then i would be very annoyed to do it for every frame in the sprite sheet, or am i thinking wrong in this part, you guys as players and end users would be annoyed if the designer forced you to define hitboxes for every frame in a sprite sheet?

Krohm, 1600x3200 is sprite sheet, its processed once to get collision masks for all frames, then when collision is checked only the current displayed frame in this image will be processed which is like 800x800 along with the small intersected area between Rects, so its not a problem and actually fast, havent noticed any peaks and lags in frametimes and CPU usage is actually 30%-50% on one core and other cores are drinking tea at 3%, but i still dont get the part of forcing CPU/GPU full sync, could you please explain as it seems a very important note?

However for multiple HitBoxes, its not viable because i feel its too hard for the end user to grasp, i thought of that earlier and to give him a window and he defines hitboxes by drawing Rects marking those areas for the Boss, but if i'm an end user/player then i would be very annoyed to do it for every frame in the sprite sheet, or am i thinking wrong in this part, you guys as players and end users would be annoyed if the designer forced you to define hitboxes for every frame in a sprite sheet?

ok, so since the player can import their own enemy's, it might be efficient to start with your grid of hitboxes which maps per-pixel, then recursively combine them to make as many large rects as you can.

Alternatively quad trees are a good wpproach to the problem as well, basically you make larger subdivided regions to test against so that you can more quickly determine when and where an collision can occur.
Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.


Krohm, 1600x3200 is sprite sheet, its processed once to get collision masks for all frames, then when collision is checked only the current displayed frame in this image will be processed which is like 800x800 along with the small intersected area between Rects, so its not a problem and actually fast, havent noticed any peaks and lags in frametimes and CPU usage is actually 30%-50% on one core and other cores are drinking tea at 3%, but i still dont get the part of forcing CPU/GPU full sync, could you please explain as it seems a very important note?
If you are doing the actual collision testing on the GPU you'll have to pull back the results somehow. The act of pulling back the collision list forces the GPU to execute its queued command until completion and initiate a transfer. I don't recall any way in D3D9 to do this without stalling. This is truly bad for performance but if you do it every frame, you might get consistent framerate anyway.

Previously "Krohm"

This topic is closed to new replies.

Advertisement