Skip to main content
GameDev.net gamedev.net
🔒 Locked

methods for drawing rain

Started by Norman Barrows Mar 20, 2014 at 10:12 PM 36 replies 17.3k views
Original Post
Norman Barrows
Norman Barrows

are there any _realistic_ looking methods for drawing rain?

i've tried all kinds of different things, including particles:

* 100 2d billboards in a 20x20 area around the camera. looks great til you look up or down.

* a "rain cone" around the camera (like a skybox). works great, til you look down.

* a "rain box" consisting of two cones pointing up and down, with a circular section between them. works great, until the ground clips the bottom cone.

* a "tall rain box " 10x10x1000 tall, made from 10x10 quads. similar to the cone, with just a small gap whne you look up, but again, clipped by the ground. mapmaps had to be tuned off to get the correct effect, without a noticeable change where mip levels changed.

* a particle system - looks great, you can see rain falling past you when you look down. but it looks like i'd need something like 10,000 to 100,000 particles visible onscreen at once. i kicked the render queque up to as high as 5000 entries for testing, using 4000 for rain, and reserving 1000 for normal uses. but for a true implementation, i'd need to reserve 3000 entries for normal uses. granted, i can draw whatever is in the queue, clear it, draw the rain, clear it again, then continue as normal, but the large number of particles is a concern. even if i bypass the queue.

i'm thinking that a combo of "rain skybox" and particle system may be the way to go.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Tispe
Tispe

What about a full screen texture with many rain drops pre-drawn, then just scroll the texture in a downward direction. Apply a dozen such layers at different speeds and distances?

Norman Barrows
Norman Barrows

What about a full screen texture with many rain drops pre-drawn, then just scroll the texture in a downward direction. Apply a dozen such layers at different speeds and distances?

this gives an effect similar to the "random 2d billboards" method (the first one listed above). works great til you look up or down. turns out, you don't need to scroll the texture. rain falls so fast, the eye can only track it for a split second. so using scrolling or particles to get a "falling" effect are unnecessary. multiple randomly animated textures, or a randomly jittered single texture works just fine.

if the effect is implemented as a single quad in front of the camera, when you look up, rain falls forward, not down. and when you look down, rain falls backward, not down.

in general, a non-particle method works ok if the quads surround the camera, and are close enough and tall enough that the gap at the top is small when you look up.

or a cone can be used instead to "close the top". but all such methods have issues where the rain quad (or cone or box) is clipped by the ground, resulting in a patch of dry ground under the camera.

apparently, only a particle system will draw rain falling down when you look down.

another downside of textured quads is its harder to add wind effects. it requires textures with rain at different falling angles, and the quads have to be turned in the correct direction, so the rain "blows" the correct way as it falls. with particles, you just add some x,z velocity based on windspeed and direction.

has anyone ever seen a game where you could look up and down, and had 1st person and 3rd person views, and had real looking rain? not just a few particles to give the impression of rain, which seems to be the common approach.

other things i've considered:

* supplementing the vertical rain quads with horizontal rain quads with just dots for the rain texture, as though you were looking at the rain head on, not from the side. this may help with the look up / look down issue.

* a combo of rain quads and particle system.

* particles that are a "cloud of rain" made from multiple mutually perpendicular quads. say 4 horizontal, 4 vertical in xy, and 4 vertical in xz. with rain texture on the vertical ones, and the rain dot texture on the horizontal ones.

good looking rain is one of the last thing left to do for the game's graphics. rain, snow, and alpha blended flames are the only graphics left to do . everything else is done. i even made an Acacia Tortilis tree model from scratch for use in tropical savanna terrain. So graphics is down to a few special effects, and perhaps some minor tweaking if room for improvement is noticed during playtesting.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
J_Glaspy
J_Glaspy

are there any _realistic_ looking methods for drawing rain?

Mr. Barrows, check your PM, please.

Tispe
Tispe




rain falls so fast, the eye can only track it for a split second. so using scrolling or particles to get a "falling" effect are unnecessary. multiple randomly animated textures, or a randomly jittered single texture works just fine.

Then why not have a texture atlas of different sized raindrops. And use the ones depending on the viewing angle?

Adam_42
Adam_42

One approach is to draw lines instead of droplets. You can place them in 3D so it looks reasonable when you look up into the sky. Here's a random photo to show roughly what you're going for, although you can get away with less of them. Having said that most of the time if you look outside when it's raining you probably won't actually see it falling at all as you need the lighting to be just right to see it, so one option is not to bother at all with rendering falling rain drops.

What you will see is splashes on the floor where the rain lands, you get different splashes depending on the surface it lands on. These don't really have to be connected to the falling drops, but you do want to avoid drawing rain underneath solid objects.

Wet surfaces also change to a darker colour, and gain extra specular reflections. This wants simulating if the rain can stop and start in the same location. It's not too hard to do that in a shader. The tricky bit is working out where to apply it.

Another effect you can implement is to simulate rain drops on the camera lens.

Take a look at http://blogs.msdn.com/b/shawnhar/archive/2009/04/01/motogp-wet-weather-effects.aspx for some more ideas.

phil_t
phil_t

See "Dynamic Weather Effects" in the book Shader X7.

But this is basically the last choice in your list in your original post. I'm sure you could get something that looks good with 10,000 particles (and that really shouldn't be much of a performance issue).

Norman Barrows
Norman Barrows




Then why not have a texture atlas of different sized raindrops. And use the ones depending on the viewing angle?

something like this was mentioned somewhere online. as i recall, they did a particle system, then behind it they did a screen space effect, with textures generated on the fly (i think) to make the rain "tilt" the right way depending on camera angle, wind etc.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Norman Barrows
Norman Barrows




One approach is to draw lines instead of droplets.

i really didn't get as far as worrying about the complexity of the particle's mesh. even with a single triangle as a 2d billboard with a rain "line" (or more likely, multiple raindrop "lines") just the sheer number of particles had me worrying. I went as high as 4000 visible onscreen at once. and it was looking like i'd need one or two more orders of magnitude above and beyond that for a decent effect.




Having said that most of the time if you look outside when it's raining you probably won't actually see it falling at all as you need the lighting to be just right to see it, so one option is not to bother at all with rendering falling rain drops.

What you will see is splashes on the floor where the rain lands, you get different splashes depending on the surface it lands on.

for the moment, i'm just working on the falling rain part. after all, falling rain is not invisible. but as you say, its almost more of a fog than particle effect.




These don't really have to be connected to the falling drops, but you do want to avoid drawing rain underneath solid objects.

Already done. : )

Fortunately, rock shelters are the only "overhang" in the game which should block precipitation. So there's separate draw rain and draw snow routines for outside, and drawing precipitation outside but not inside a rock shelter, IE draw rain, draw snow, draw rain outside of rock shelter, and draw snow outside of rock shelter. the game uses the player's location to determine if they are under the overhang, and which drawing routine to use. getting the transition right took a bit of tweaking. but it works great, in first or 3rd person view. As i recall, skyrim (like oblivion) still doesn't do this.




Another effect you can implement is to simulate rain drops on the camera lens.

Paleolithic setting - thus no lens effects. I've been thinking about playing around with the FOV some more, to try to get a more "true-eye" projection going. humans have a stereoscopic field of view of about 90 degrees horizontal, but a peripheral field of view of 120 to 150 degrees horizontal. vertical stereo and peripheral FOVs are both about 90 degrees. the aspect ratio is about 3:1, depending on the shape of the face around the eye. anyone know if directx can do something like this? perhaps with letter boxing to get the desired aspect ratio, once the FOVs are correct?

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Norman Barrows
Norman Barrows




See "Dynamic Weather Effects" in the book Shader X7.

But this is basically the last choice in your list in your original post. I'm sure you could get something that looks good with 10,000 particles (and that really shouldn't be much of a performance issue).

thanks Phil!

perhaps i'll have another go at particles, bypass the render queue, and just blast them out in draw_immediate mode. then i don't have to worry about increasing the render queue size. actually, come to think of it, despite the fact that the queue size is static, it tracks the number of entries, and only iterates over those. so kicking it up to 15000 for rain is ok, even if it only needs maybe 3000 the rest of the time. the render queue is filled and drawn multiple times to draw a single frame, with ~2000 entries the normal max usage at any given point (other than rain particles).

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Norman Barrows
Norman Barrows




The good attempts that I've seen have used lots of particles. You should check out the Rain sample from the Nvidia SDK. I also noticed in that in the recent Assassin's Creed 4 GDC presentation there were some slides about their rain.

yes, i think lots of particles ( or faking that somehow) is the way to go. now if i only had a Cray on every users desk.... .

"Put a CRAY on every users desk and i'll build you a REAL game!" - a famous quote of mine

I'm pretty sure i've seen the Nvidia stuff, i'll have to check out the assasin's creed, though. I'd like to take a closer look at that franchise, i keep hearing good things about it.

BTW - big Rocko fan here! used to watch it all the time.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Norman Barrows
Norman Barrows

Well, after continued thinking about it, testing various concepts, etc. i came up with a "rain cylinder". its in 3 parts: the tube shaped walls, and the top and bottom caps. the walls use cylindrical texture mapping, and the end caps use planar. the walls use animated rain textures. the end caps also use the same animated rain textures, even though they should really be textures with a bunch of rain dots, not lines. but the scale is small, so its hardly noticeable. its drawn centered on the camera with alpha testing. just a single 12 sided cylinder with alpha test and animated textures. results are quite nice in both 1pv and 3pv. rain looks correct when looking up, ahead, and down. no wind effects though, unfortunately. something like that plus particles may do the trick.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
mark ds
mark ds

How about using a rain cone? The rain emanates from a point above your head as a cylindrical function. If you use particles, you can also use hit testing to limit it's visual impact. If you need driven rain, you can skew the angle at which it falls - just make sure the rain cone is large enough to accommodate it.

Hodgman
Hodgman

Last time I made a simple rain effect, I just overlaid the world with a virtual, repeating grid of vertical planes (if y=up, then z-facing and x-facing). I then selected the two closest x-facing and z-facing planes in front of the camera, and drew them with a scrolling raindrop texture. As the camera nears a plane, it is faded out, and the farther one on the same axis is faded in, so you can't 'intersect' them and realize that they're just planes.

For extra effect, you can slowly rotate the whole grid to hide the fact that it's made of axis aligned planes, and I changed the angle of the scrolling texture to correlate to the direction of the game's wind variable.

9dOcOLI.png

Norman Barrows
Norman Barrows




How about using a rain cone? The rain emanates from a point above your head as a cylindrical function. If you use particles, you can also use hit testing to limit it's visual impact. If you need driven rain, you can skew the angle at which it falls - just make sure the rain cone is large enough to accommodate it.

tried that one. worked great looking up, but not down. either the ground would clip it, or the simple conic mapping made the bottom look "wrong" (rain going sideways). that was before i got into using different texture projections for different parts of the "rain skybox".

thought about trying 2 cones, one above and one below, but again, ground clipping could be an issue.

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Hodgman
Hodgman




ground clipping could be an issue.
For any of these geometry-based methods, you'd ideally fade out the texture based on height above the ground, so that you can't see the geometry intersecting with the ground.

These days, you'd do that by sampling the depth-buffer and comparing it against the depth of the 'rain' pixel, fading out if they are too close together. Without shaders, you could add some extra vertices to your geometry, and set the alpha value of the bottom-most verts to zero.

Styves
Styves

For CryENGINE SDK's snow effect, I created a simple vertex mesh with randomly positioned vertices. This mesh contained something like 100 to 1000 vertices. Each vertex contained a position and a random color. Then I instanced it and rendered it at different locations around the camera and applied turbulence and wind in the vertex shader to each vertex separately using their random color (from the vertex and the instance) to create "randomness".

The vertices were then expanded (DX9: store 6 vertices instead of 1, all with same info, and expand, DX10: use geometry shader) and facing the screen, with some stretch based on their movement direction - no quad is ever smaller than a few pixels, to avoid sub-pixel issues (and potential small-triangle problems). The pixel shader sampled the screen buffer and a normal map over each small quad and applied some fake snow-flake like refraction and lighting. The texture was an atlas too, so a simple random offset into the atlas gave a different texture, making it look like the snowflakes are all unique.

The whole thing took less than ~0.025ms or something like this (been about a year since I worked on it, so may be a bit higher or lower). There were something like 10,000 particles at a time with default settings. You can easily increase it into the millions without going over 1ms (likely way more than millions if you want to break 1ms!).

I prefer this so much more than silly cone meshes or scrolling textures as it provides dynamic snow/rain fall for very cheap that has varying motion with turbulence and can be affected by forces in the world (such as localized wind sources). Cones suffer from some really weird looks, and if they follow the camera the worst thing happens: the rain moves with you! Nothing sucks more in a rain technique than fast movements and rain that follows you. smile.png

Norman Barrows
Norman Barrows

Last time I made a simple rain effect, I just overlaid the world with a virtual, repeating grid of vertical planes...

very slick. similar to the non-particle effects used in the best academic efforts I found mention of online.

but i tried vertical planes in xy and xz, in a 4 unit bbox rad (cube) around the camera, and 0.1 unit spacing between planes. looked great, but even at 0.1 spacing (1.2" or about 3cm at a scale of 1 d3d unit = 1 foot) you could still see a gap between planes when looking up. same thing looking down from high above. looking down when low, the ground clipped the quads before the gap was noticeable. but the perspective foreshortening of the planes going up and down worked quite well. looked like rain falling around you, except straight up and down. granted you could see the top edges of the planes, but this could be fixed via geometry or fading. but the gap in the middle was another issue. it was at that point that i became convinced that some sort of horizontal or non-vertical plane or quad would be required for a non-particle "rainbox" approach. that's when i tried a rain tube, followed by a rain cylinder with cylindrically mapped walls, and planer mapped caps.

were the planes you used very tall and close so that looking up wasn't an issue? could you see a square hole of no rain in the center looking up?

Norm Barrows Rockland Software Productions "Building PC games since 1989"</
Norman Barrows
Norman Barrows




This mesh contained something like 100 to 1000 vertices....

The vertices were then expanded (DX9: store 6 vertices instead of 1, all with same info, and expand, DX10: use geometry shader)...

no quad is ever smaller than a few pixels,

so each point in the original mesh was expanded to become a quad, correct?




Then I instanced it and rendered it at different locations around the camera

how many instances in what kind of radius? did it require a large number at close range?




The texture was an atlas too, so a simple random offset into the atlas gave a different texture, making it look like the snowflakes are all unique.

Clever! ; )




The whole thing took less than ~0.025ms or something like this (been about a year since I worked on it, so may be a bit higher or lower). There were something like 10,000 particles at a time with default settings.

impressive numbers. particle system, updated in the vertex shader, with wind, lighting, and random textures. and you used quads. were they 2d or 3d billboards? 3d i suppose, eh?




Cones suffer from some really weird looks, and if they follow the camera the worst thing happens: the rain moves with you! Nothing sucks more in a rain technique than fast movements and rain that follows you.
'

'

except rain that doesn't!

when playing with particles, at first the rain fell too slowly. if you hit sprint, the rain flew back at you like you were in a racecar, or going into warp speed or something! .

then i had issues with the player "outrunning" the rain. changing the order to "move, regen, draw" and making it regenerate particles at a random location in the "particle box" around the camera fixed that.

but as stated above, i kicked the render queue up from 3000 to 5000 entries and drew 4000 raindrop cubes visible onscreen at once. and it looked like i'd need 10 times as many.

in the past, i've discovered that in general, snow requires fewer particles than rain. i think its because we tend to render fluffy flakes, not powder. so fewer particles are required to achieve the desired density due to the larger quad size. perhaps snow innately has a lower scene density as well.

but i have yet to get down and dirty with it. bypass the render queue, use Zdraw_immediate. they're dynamic, so i couldn't pre-generate a single large static mesh each frame. could go dynamic buffers... fixed function instancing... break down and write a shader....... start with brute force. the abrash and ID way. 10K particles visible, perhaps 80k to 100K particles in the system, in the "particle box" around the camera. moving particles is cheap. drawing visible ones isn't. about 10K DIP calls of one static quad each. really screams for instancing, though....

Norm Barrows Rockland Software Productions "Building PC games since 1989"</

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.