GPWiki.org
GPWiki.org
It is currently Sat May 25, 2013 3:33 am

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Thu Oct 20, 2011 3:18 am 
Grand Optimizer
User avatar

Joined: Mon Jan 17, 2005 6:01 pm
Posts: 352
Location: Canada
Hi again,

So I've got a simple tank game on the go, and ive run into a strange problem. It's 2D, top down. I've set it up such that you can rotate the turret independant of the tank's main chassis. Ive setup a simple shadow effect on both the chassis and the turret (Basically, wherever i've drawn the tank, i basically draw it again as a custom black/transparent color.. just off to the right and down a bit, and a bit lower down in the layer depth).

So anyways, it all looks great except for where the shadow of the turret overlaps the shadow of the chassis I get the resulting extra dark shadow spot, which looks goofy. I saw somewhere in the drawing options you can set different blend modes (alphablend, multiply, etc..) Im using alphaBlend right now. I tried messing with the other ones but errors ensued. Plus, im using transparent PNGs for the sprites so im thinking i probably need "AlphaBlend".

Anyways. Any suggestions would be welcome. I'm sure lots of designers run into this very problem, but in most games ive played, it seems to be solved fairly elegantly. Any help?

Thanks!

_________________
"None are more hopelessly enslaved than those who falsely believe they are free."
"It is no measure of health to be well adjusted to a profoundly sick society."
"Hope is the first step on the road to dissapointment." -Jonah Orion
http://tankzgame.blogspot.com


Top
 Profile  
 
PostPosted: Thu Oct 20, 2011 10:50 am 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3735
Location: South Africa
Depending how you're doing the shadow drawing, you could take all your shadow graphics and get rid of the alpha on them, making them pure black, with alpha feathering on the edges. Then when you draw the shadows, draw all the shadow graphics to a separate surface and then blend that surface as a whole onto the layer just under your characters.

Image
On the left are two shapes of pure black with feathering alpha-blended together. On the right they are on top of a background layer with alpha set to 60%.

If you really want to get fancy you can create a shadow of your objects dynamically by taking their graphic, setting all the visible pixels to black and then applying a Gaussian blur on the result.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Thu Oct 20, 2011 11:06 am 
Corpse Bride
User avatar

Joined: Tue Jul 01, 2008 11:44 pm
Posts: 2217
Location: England
The old fashioned way is to make a shadow use an alternating black/white checkerboard pattern, and to AND that with the destination image.

As long as the black pixels line up, you can paste it as many copies of it as you like, and you'll always get a 50% transparency effect.

The correct name for the effect is "stippled alpha".

_________________
I ain't pushing no moon buttons.


Top
 Profile  
 
PostPosted: Thu Oct 20, 2011 9:35 pm 
Grand Optimizer
User avatar

Joined: Mon Jan 17, 2005 6:01 pm
Posts: 352
Location: Canada
IGTHORN wrote:
If you really want to get fancy you can create a shadow of your objects dynamically by taking their graphic, setting all the visible pixels to black and then applying a Gaussian blur on the result.


?

How do i throw feathering/blurring/other effects on my sprites at runtime? The only FX i see in the draw method are 'flipHorizontal' and stuff like that.

_________________
"None are more hopelessly enslaved than those who falsely believe they are free."
"It is no measure of health to be well adjusted to a profoundly sick society."
"Hope is the first step on the road to dissapointment." -Jonah Orion
http://tankzgame.blogspot.com


Top
 Profile  
 
PostPosted: Thu Oct 20, 2011 10:24 pm 
Corpse Bride
User avatar

Joined: Tue Jul 01, 2008 11:44 pm
Posts: 2217
Location: England
Behold: The Blend Calculus!

A = original image
B = shadow 1
C = shadow 2
p = alpha

The combined shadow:
Let S = B*C

You want to mask the original image with the combined shadow, using alpha=p
= A * [(1-p) + S*p]

Let us rearrange this expression
= A*B*C*p + A*(1-p)



Putting that into algorithmic form:
Step one: M := A
-- Create a copy the rectangle A you are going to be drawing over, call it M.

Step two: A := A*B*C
-- Paint black shadows into the original image.

Step three: A := A*p + M*(1-p)
-- Alphablend the copy you made back into the original image, with alpha = (1-p)

_________________
I ain't pushing no moon buttons.


Top
 Profile  
 
PostPosted: Fri Oct 21, 2011 8:46 pm 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3735
Location: South Africa
Gaussian blurring is achieved by recalculating the value of each pixel by multiplying out some factor of its neighbours. This is called convolving the image with a filter. The weights which you apply to the neighbours are determined according to the Gaussian (aka Normal) distribution.

Horrible, hard to understand literature: http://en.wikipedia.org/wiki/Gaussian_blur

Basically, you loop through each pixel in the image you want to blur and then write the output to a new image. Here's a code sample:
Code:
    //2   4   5   4   2
    //4   9   12  9   4        1
    //5  12   15  12  5    x  ---
    //4   9   12  9   4       159
    //2   4   5   4   2

    int getIntensity(int x, int y){
        if (x<0 || y<0 || x>=width || y>=height) return 0;
        return imageData[y][x];
    }

    void blur(){
    std::vector< std::vector<int> > imageDataTemp = imageData;
    short kernel[5][5] = { {2,4,5,4,2}, {4,9,12,9,4}, {5,12,15,12,5}, {4,9,12,9,4}, {2,4,5,4,2} };
    for (int x=0; x<width; x++){
        for (int y=0; y<height; y++){
            double result=0.0;
            for (int ky=-2; ky <= 2; ky++){
                for (int kx=-2; kx <= 2; kx++){
                    result = result + getIntensity(x+kx,y+ky)*kernel[kx+2][ky+2];
                }
            }
            result /= 159;
            if (result>255) result=255;
            imageDataTemp[y][x] = static_cast<int>(result);
        }
    }
    imageData = imageDataTemp;
    }


My getIntensity function is returning a pixel value in the image, but when a pixel is requested from beyond the bounds of the image, then it only returns 0. In truth this is less than desirable in the usual case, as it's making up data that will skew the results of the blur on the edges of the image. A better solution would be to use more complicated logic to return the mirror pixel from the edge. I.e. if pixel (-1,-19) is requested, return pixel (1,19) from the real image.

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Sat Oct 22, 2011 2:32 am 
*sniff sniff*

I smell HLSL. I'd better learn that. Right now I'm using straight up vanilla XNA. I dont know the first thing about shaders, how they work, how to create them or even how to implement them. I'l look for a book on the subject at chapters (because 99.999% of all programming related references i find on the internet are like "Bobby-Ray's Programmin' WEEBSITE! Yeehaw chek out mah soorrceee KODE!!11!1!one!!1!"

lol


Top
  
 
PostPosted: Sat Oct 22, 2011 8:16 am 
Dexterous Droid
User avatar

Joined: Wed Aug 18, 2004 7:40 pm
Posts: 3735
Location: South Africa
Well, you don't absolutely need shaders for any of this. Shaders would let you do the processing much faster but learning how shaders work is a bit trippy. Implement them first in regular code, you'll find it'll be much easier to transfer it to HLSL after that and will also convince you that your algorithm works and any problems are due to HLSL issues.

Riemer has a pretty nice intro to HLSL. (The page navigation is on the rightmost column on his website)

_________________
Whatever the mind can conceive and believe, it can achieve


Top
 Profile  
 
PostPosted: Sat Oct 22, 2011 1:07 pm 
Yeah I was lookin at that one. It looks very nicely done but it seems geared towards 3D(which i know nothing about). Maybe I could adapt it somehow.


Top
  
 
PostPosted: Sat Oct 22, 2011 2:20 pm 
Corpse Bride
User avatar

Joined: Tue Jul 01, 2008 11:44 pm
Posts: 2217
Location: England
If graphics were vector based, it would make sense to do a gaussian blur of the shadow, because the geometry can rotated and distorted in any number of ways that can't be adequately approximated with bitmaps.

But here, you're just using bitmap sprites. The shadow of a fixed sprite is itself fixed and doesn't need to be computed over and over on the fly. A gaussian blur seems unnecessary to me.

_________________
I ain't pushing no moon buttons.


Top
 Profile  
 
PostPosted: Sun Oct 23, 2011 12:24 pm 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3810
Location: Ferriday, LA, US
Jasmine wrote:
If graphics were vector based, it would make sense to do a gaussian blur of the shadow, because the geometry can rotated and distorted in any number of ways that can't be adequately approximated with bitmaps.

But here, you're just using bitmap sprites. The shadow of a fixed sprite is itself fixed and doesn't need to be computed over and over on the fly. A gaussian blur seems unnecessary to me.

Apparently the OP's sprites can rotate and such, so it wouldn't necessarily be as easy as tacking a shadow effect onto the images.

It's too bad that XNA doesn't offer more in the way of raster composite operations. I know that any of that can be achieved with HLSL, but the math for that sort of thing is usually only found in rare, dusty, and usually ridiculously expensive texts.

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Sun Oct 23, 2011 4:08 pm 
Corpse Bride
User avatar

Joined: Tue Jul 01, 2008 11:44 pm
Posts: 2217
Location: England
rotInMilc wrote:
Jasmine wrote:
If graphics were vector based, it would make sense to do a gaussian blur of the shadow, because the geometry can rotated and distorted in any number of ways that can't be adequately approximated with bitmaps.

But here, you're just using bitmap sprites. The shadow of a fixed sprite is itself fixed and doesn't need to be computed over and over on the fly. A gaussian blur seems unnecessary to me.

Apparently the OP's sprites can rotate and such, so it wouldn't necessarily be as easy as tacking a shadow effect onto the images.


If sprite bitmaps can rotate, then so can shadow bitmaps.

_________________
I ain't pushing no moon buttons.


Top
 Profile  
 
PostPosted: Mon Oct 24, 2011 1:00 am 
Harmlessness does no harm
User avatar

Joined: Tue Sep 14, 2004 8:37 pm
Posts: 3810
Location: Ferriday, LA, US
Jasmine wrote:
If sprite bitmaps can rotate, then so can shadow bitmaps.

Of course. :) But then there's still the problem of the alphas from different shadows being added to each other, and making the sum darker than it should be.

_________________
What most people don't understand about "enlightenment" is that it is not an end-goal; but where you find yourself just before taking a new "first step."


Top
 Profile  
 
PostPosted: Mon Oct 24, 2011 11:04 am 
Corpse Bride
User avatar

Joined: Tue Jul 01, 2008 11:44 pm
Posts: 2217
Location: England
rotInMilc wrote:
Jasmine wrote:
If sprite bitmaps can rotate, then so can shadow bitmaps.

Of course. :) But then there's still the problem of the alphas from different shadows being added to each other, and making the sum darker than it should be.


It's only a problem if it's done incorrectly.
viewtopic.php?f=7&t=10896#p139594

_________________
I ain't pushing no moon buttons.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group