# Creating a rain effect...

• 12-02-2007
Raigne
Creating a rain effect...
I am creating a 2D RPG type game with Dark GDK, and I cant seem to figure out how to create a decent looking rain effect. I tried creating 4 images ( 1x5, 1x8, 1x11, 1x13 ) and just randomly mixing them as sprites, but they don't look right. Any help would be appreciated. It doesn't have to be in Dark GDK, but even theories would be helpful.
• 12-03-2007
mike_g
You could have an object for each rain drop which would be drawn as a vertical, or slightly angled line using pixel writing operations.

You could then get the colour behind the pixel to draw and blend it with white to a varying degree. Something something like the base pixel will be lightened a lot and the trailing pixels would falloff.

For this you would need a line drawing and a colour blending algo. I can post them if you need it.
• 12-03-2007
cboard_member
>> For this you would need a line drawing and a colour blending algo.

I'd like to see the colour blending algo if I may - I'm about to go hunting for information on this myself :)
• 12-03-2007
matsp
Generally, this is an "alpha blend". Each pixel is defined as ARGB, and you blend a source and destination pixel by:
Code:

`result{R,G,B} = source{R,G,B} * A + dest{R,G,B} * (1.0-A)`
Where R, G, B and A are floating point numbers in the range 0..1 - you can do this using integer math, which makes the calculation a bit more complex, but in essence the same thing.

--
Mats
• 12-03-2007
mike_g
Quote:

I'd like to see the colour blending algo if I may
Heres one for 2d I made:
Code:

```Uint32 ColourBlend(Uint32 rgb_1, Uint32 rgb_2, Uint16 alpha_1) {     Uint16 alpha_2 = 256 - alpha_1;     Uint32 rb_1 = ((rgb_1 & 0x00FF00FF) * alpha_1) & 0xFF00FF00;     Uint32 g_1  = ((rgb_1 & 0x0000FF00) * alpha_1) & 0x00FF0000;      Uint32 rb_2 = ((rgb_2 & 0x00FF00FF) * alpha_2) & 0xFF00FF00;     Uint32 g_2  = ((rgb_2 & 0x0000FF00) * alpha_2) & 0x00FF0000;     rb_1+=rb_2; g_1+=g_2;     return (rb_1 | g_1) >> 8; }```
The alpha should be set between 0 and 255. It avoids floating point maths, and does the red and blue elements in one go. It does however delete the stuff in the alpha Byte so if thats important you may want to modify it. Its fast for software rendered stuff but if you're using 3D then OpenGL and DirectX should be able to do fast alpha in hardware.
• 12-03-2007
Raigne
wow, rain is a little more complex than i had anticipated. I will try writing the code, a little later on , and will post my results. Thank you.
• 12-03-2007
VirtualAce
I've implemented this effect in my tile engine as a vertex array of lines.

Here are some rudimentary formulas for the effect.
Code:

```rain_length =10 + rand() &#37; 20; rain_angle = -60 + rand() % 120; top_rain.x = rand() % width; top_rain.y = rand() % 20; top_rain.z = rand() % 20; bot_rain.x = top_rain.x + cos(DEGTORAD(rain_angle)) * rain_length; bot_rain.y = top_rain.y + sin(DEGTORAD(rain_angle)) * rain_length; bot_rain.z = top_rain.z; rain_speed = 20 + rand()% 20;```
• 12-03-2007
Raigne
Bubba,
Is that for a 2D effect, or 3D? I just noticed it has a z axis as well.
• 12-04-2007
mike_g
Its in 2d but uses z-ordering, which is something you might want to think about doing. Unless the games completely flat the more distant rain would hit the ground higher up on the screen, it would also fall slightly slower, and fall behind sprites that are closer. It woud defenitely give a much better fell of depth.
• 12-04-2007
cboard_member
matsp & mike_g: Thanks for the info! :thumbsup:
• 12-04-2007
Raigne
The z-ordering will complicate things a little more but i will give it a shot.
• 12-04-2007
VirtualAce
It's not Z-ordered per se but it uses Z so that the rain effect overall is much more convincing. Since the Z is being taken into account to alter the speed of the rain, the same speed factor could be used for all of the rain segments.
Rain speed in this instance is directly proportional to Z distance.

I know nothing about Dark GDK but if it's a game dev kit it may become limiting when it comes to direct manipulation of vertices. The ideal setup for a Direct3D app would be to lock the buffer, write, unlock, increment offset, lock, unlock, etc. This way the video card can render the portion of the vertex buffer you just locked at the same time you are loading into or altering the next portion.