2D shadow
Hi all,
before posting here i looked around over google for a whole afternoon+night, so i finally decided to post.
BTW: I even went to the library and 2 bookshops to check on books related to 2D shadow( real-time software rendering ) but i got nothing.
Most of the time the shadowing effects are implemented using 3D graphic API(DirectX/OpenGL...), but now i'm doing a simple 2D program using GDI and i would like to add some cool and simple shadowing effects(as realistic as possible). I just need to be pointed out with theoritical papers or peace of codes on the subject.
Please does anyone have a clue?
It's really urgent, please!
I forgot to say that i saw this page on Dynamic 2D Soft Shadows, it has another link to this forum, unfortunately, the link seems to be broken :(
Quote:Original post by darookie
remi: Big thanks for pointing us to that article! It's really good.
++rating.
No big deal man.
Guess it was a network problem, in fact, i can open the page now. But it seems to be using OpenGL(i don't want to).
it depends on what kind of 2d game it is.
if its 2d isometric then you can put cool shadows for your characters by masking
them and skewing them away from the direction of the light.
and gdi might have stuff for that, im not sure how game worthy it is.
shadowing your buildings would be a bit harder, render black polygons on the
screen pointing away from the light source like shadow volume style, like that
article suggests, you could probably still do it with the basic graphic interface. (which is slower than direct draw btw)
then merge em with your traditional scene.
maybe youll have to write your own optimized bitmap drawing functions if gdi
doesnt have functions for things.
i love 2d by the way.
well thats my 2 cents.
if its 2d isometric then you can put cool shadows for your characters by masking
them and skewing them away from the direction of the light.
and gdi might have stuff for that, im not sure how game worthy it is.
shadowing your buildings would be a bit harder, render black polygons on the
screen pointing away from the light source like shadow volume style, like that
article suggests, you could probably still do it with the basic graphic interface. (which is slower than direct draw btw)
then merge em with your traditional scene.
maybe youll have to write your own optimized bitmap drawing functions if gdi
doesnt have functions for things.
i love 2d by the way.
well thats my 2 cents.
Hi!
It would be nice if you tell what kind of game you are programming.
I dont know if this may be helpful. I did something like that for my 8bpp 2d engine. A link to a shot:
http://www.spritekin.com/kengine/screenshots/screen1large.jpg
The idea is this:
a. All the light computations are done in 'world' space. In that space you use floating point coordinates. If you are using tiles your tiles will be square in this world space. It doen't matter if your game is isometric. World space is a top view of your game so they should be squares. If your engine is top view... it will be easier.
b. Select all the light emmitters that may create some king of illumination in your scene. Computations are heavy, so the more lights in scene, the slower it will be so use lights carefully.
c. Select all corners of the tiles and fill the in your light buffer. The light buffer is just a float 2D array with the dimensions of the viewable area. (say 10*10, 20*20 or anything. This array will hold the light contributions for each corner of each tile. In 2d apps this corner-light-buffer only requires a floating point number going from 0 to 1 (or any other limits you consider). In 3D based apps you can set each point to 3 floats in order to hold RGB light contributions. At the beginning, each float should be set to the value of the ambient light (usually 0 for a dark place).
d. For each corner compute the light contribution from each light affecting the scene (as you see, more lights, more computations). You may exclude many lights affecting a point by using a simple circle test or square test. Many optimizations available here.
d.1. In case you want more real light, more computations are required. Make a selection of any opaque objects currently in your view area. Opaque objects are those that you consider may block light like columns, doors or walls. Then, before processing the lights (as in d), make a subselection of opaque objects that are near each light. The same opaque object may be associated to more than one light depending the radius of the light. When you have these subgroups, each time you compute the light contribution to a point, you must check the line of light from the light source to the target point. If any opaque object is in the line, the light is considered blocked.
e. When all the process in c is finished, you have filled your light buffer. Lower values mean dark places. These values should be between 0 and 1. The average value of 4 corners is the overall color of the tile in case of 2D. In case of 3D just use the colors of each corner in orderand let the card interpolate the values for a nice shade effect.
f. Once you render the tiles, the objects in the scene can use the light information so they can be rendered lighter or darker.
Thats all, I hope I was helpful.
Luck!
Guimo
It would be nice if you tell what kind of game you are programming.
I dont know if this may be helpful. I did something like that for my 8bpp 2d engine. A link to a shot:
http://www.spritekin.com/kengine/screenshots/screen1large.jpg
The idea is this:
a. All the light computations are done in 'world' space. In that space you use floating point coordinates. If you are using tiles your tiles will be square in this world space. It doen't matter if your game is isometric. World space is a top view of your game so they should be squares. If your engine is top view... it will be easier.
b. Select all the light emmitters that may create some king of illumination in your scene. Computations are heavy, so the more lights in scene, the slower it will be so use lights carefully.
c. Select all corners of the tiles and fill the in your light buffer. The light buffer is just a float 2D array with the dimensions of the viewable area. (say 10*10, 20*20 or anything. This array will hold the light contributions for each corner of each tile. In 2d apps this corner-light-buffer only requires a floating point number going from 0 to 1 (or any other limits you consider). In 3D based apps you can set each point to 3 floats in order to hold RGB light contributions. At the beginning, each float should be set to the value of the ambient light (usually 0 for a dark place).
d. For each corner compute the light contribution from each light affecting the scene (as you see, more lights, more computations). You may exclude many lights affecting a point by using a simple circle test or square test. Many optimizations available here.
d.1. In case you want more real light, more computations are required. Make a selection of any opaque objects currently in your view area. Opaque objects are those that you consider may block light like columns, doors or walls. Then, before processing the lights (as in d), make a subselection of opaque objects that are near each light. The same opaque object may be associated to more than one light depending the radius of the light. When you have these subgroups, each time you compute the light contribution to a point, you must check the line of light from the light source to the target point. If any opaque object is in the line, the light is considered blocked.
e. When all the process in c is finished, you have filled your light buffer. Lower values mean dark places. These values should be between 0 and 1. The average value of 4 corners is the overall color of the tile in case of 2D. In case of 3D just use the colors of each corner in orderand let the card interpolate the values for a nice shade effect.
f. Once you render the tiles, the objects in the scene can use the light information so they can be rendered lighter or darker.
Thats all, I hope I was helpful.
Luck!
Guimo
Hi all, and thank you very much for your useful replies!
What i was interested in is something like this. Look at that drop shadow effect, it would be really nice to implement something like that without using any external library.
What i was interested in is something like this. Look at that drop shadow effect, it would be really nice to implement something like that without using any external library.
I guess what you could do is to take the mask from your image (coloured the colour of your shadow) then blur it by taking each pixel, adding up the values of the pixels around it, then divide by 9 and set the pixel to that value. There are probably better ways to blur the mask, but then just overlay this onto the world. Naturally, this isn't very fast.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement