Skip to main content
gamedev.net
🔒 Locked

Simulating wind

Started by ZealousEngine Jul 14, 2006 at 5:09 PM 25 replies 9.1k views
Original Post
ZealousEngine
ZealousEngine
Im looking for a basic equation that simulates a wind vector (2d is fine). I would like to be able to control the direction and intensity of the wind, but I also want it to have some natural chaos too. So if there is a 'north wind' with x strength, it will randomly fluctuate in strength slightly, and shift a little to the east/west too. Also I had a question about animating objects with the wind - Right now im using a simple sin wave to move the top verts of my grass plains. The problem is, the sin wave moves the grass all the way back, and all the way forward. It seems like the grass should move all the way forward (in the direction of the wind vector), but then only PARTIALLY back against the wind. How would you write that? Thanks in advance!
ZealousEngine
ZealousEngine
That will work for wind intensity (although only for the x axis), but what about wind direction? And how would you get the grass to move forward 100%, but not quite all the way back in the opposite direciton?
CrazyCdn
CrazyCdn
Quote:
Original post by ZealousEngine
That will work for wind intensity (although only for the x axis), but what about wind direction? And how would you get the grass to move forward 100%, but not quite all the way back in the opposite direciton?


I'm physically wasted and mentally dead so bare with me (too much sun I think and an overall lack of water (I ran out, sue me)). But a spring system on your grass would work. Give it a "push" then let the grass physics take over to bring it back.
"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin
ZealousEngine
ZealousEngine
Hmm how could you simulate a spring on a per vertex level inside a shader? I guess you could store the 'center position' of the grass quad in a uv coord, and 'pull it back' to that position...

So that might work to prevent a full 'recoil', but what about chaos? I want all the grass to be pushed in a little random direction. I could store a random seed in a uv coord, but how would you USE it?

And to calculate the wind vector itself, im guessing just a random number push in the x/y direction (and maintain velocity, kind alike asteroids)
CrazyCdn
CrazyCdn
Well one big thing you failed to mention was using it in a shader. I had/have no idea how you're doing grass :)
"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin
ZealousEngine
ZealousEngine
Yeah sorry I do plan on using this in a shader, but I still need to calculate the wind vector in my main app, so that part doesnt have anything to do with the shader.

So I think I got a wind vector (I just push a vector in a random direction, kinda like asteroids). Now I need to 'use' that vector inside my shader. The most elegant 'grass animation' solution ive seen (and ive been reading millions of them all this week), is the one in my gpu gems vol 1 book. What they do (although they dont show you what the code looks like!!!), is store the center position (of a grass cross plain) in a uv coord, then perform this very vague funciton (makes me mad I spent so much on this damn book!!) - >

float3 vObjectTranslation = CalcTranslation(v.ObjectPosition, fTimeStamp, vWindDirection, fWindStrength);temp.vPosition = v.vPosition + vObjectTranslation;


So this "objectTranslation" function is being run inside the shader on a per vertex basis. It takes the "objectPosition" (which is the center of the grass xplain, stored in a uv coord) and somehow uses that value to give the animation (based on the wind vector and wind strength) some local chaos.

So two questions

1.) Whats going on inside this objectTranslation function!!!!? How is it offsetting the wind by a random direction/strength based on the 'center position'?

2.) And also, inside that translation function I imagine it shows how you get the 'springy' result, so when the grass blade is pushed against the wind, it doesnt recoil all the way back AGAINST the wind (assuming they are using a sin wave, which they say they are. Again, NO CODE! ).
vangogh_umbc
vangogh_umbc
If I were going to simulate wind sweeping across terrain, I'd create some 2d textures with wind velocities stored as RGB, and then project them onto the terrain and simulate wind movement by manipulating the texture coordinates. I'd imagine you could get some good results doing something along these lines
ZealousEngine
ZealousEngine
Ive thought about using a wind map (at this rate I may have to). But does anyone have an idea what those above calculations would look like? That wasy I can compare the two methods
alvaro
alvaro
I thought about this problem a while back, but I never implemented any of it. Your wind can be defined by a function Wind(x,y,z) (or just Wind(x,y) if you only want this for grass) that returns a vector which is just the general direction of the wind plus some Perlin-style noise. You can compute Perlin-style noise in the GPU by combining textures at different scales, as several articles about cloud generation show. It would be good if the CPU could reproduce the same wind function, so you can have other objects animated in a consistent way.

As for the motion of the grass, it shouldn't be that hard to simulate a little harmonic oscillator for each blade or bunch of blades. Of course you need to store some information per blade (like the current position and the velocity, or the current position and the previous position, if you want to use verlet integration), which I guess can be done using a texture in the GPU.

ZealousEngine
ZealousEngine
Yeah im leaning more twards the windmap idea (thanks again thats pretty clever). That way I just set my uvs once when the grass is planted, and everything will animate via a simple scrolling texture. If I can get my field of grass big enough ill bet youll really notice the ripples...
lonesock
lonesock
Quote:
Original post by ZealousEngine
1.) Whats going on inside this objectTranslation function!!!!? How is it offsetting the wind by a random direction/strength based on the 'center position'?

2.) And also, inside that translation function I imagine it shows how you get the 'springy' result, so when the grass blade is pushed against the wind, it doesnt recoil all the way back AGAINST the wind (assuming they are using a sin wave, which they say they are. Again, NO CODE! ).

I belive on nvidia's website you can download the code.
ZealousEngine
ZealousEngine
Akk I think I may have misunderstood what a "wind map" is. I tryed to implement something like this...

I set the a uv coord layer for all my grass objects to be the 'wind uv'. Imagine looking down on a grass patch from a birds eye view, and each grass cross plain would recieve a uv coord based on its x/z position. Then I figured to 'animate' the grass, I would just scroll this wind texture (as if it were moving along the x/z plain), and sample the texture color for each vert. Then all you need to do is multiply this 'wind intensity' color by the vertex transformation, and youre done.

Now in my mind, that would be super efficient, BUT im starting to think its impossible to sample a texture from the vertex shader (would explain why things keep crashing). Why though? It makes no sense! Assuming the image is loaded and ready to go, shouldnt we be able to sample it form anywhere in the hlsl file?

Well unless somebody can think of a way to sample a texture from the vertex shader, im gonna have to think of another way. vangogh_umbc you mentioned using a windmap, how would you implement it?

*edit - Wait, wouldnt my idea still work if you just used an array of data, rather than an image for the 'wind map'. That way you could still do your displacement in the vertex shader (it would require you do custom bilinear interpolation inside the vertex shader, but sure beats doing it on a per pixel basis). Think it would work?

[Edited by - ZealousEngine on July 21, 2006 8:46:36 AM]
alvaro
alvaro
Quote:
Original post by ZealousEngine
[...]

Now in my mind, that would be super efficient, BUT im starting to think its impossible to sample a texture from the vertex shader (would explain why things keep crashing).

I don't have much experience with vertex shaders, but you can definitely read texture data from them:
http://www.google.com/search?hl=en&q=vertex+shader+texture+data&btnG=Google+Search
Kalidor
Kalidor
As of right now NVIDIA's SM 3.0 cards are the only ones that have vertex texture fetching. ATI doesn't have any cards available yet that support it.
Quote:
Original post by ZealousEngine
...wouldnt my idea still work if you just used an array of data, rather than an image for the 'wind map'...
Yes, you can send the wind vectors as a generic vertex attribute, similar to how you would send tangent vectors.
ZealousEngine
ZealousEngine
Correct me if im wrong, but it requires shader model 3.0 :(
ZealousEngine
ZealousEngine
@kalidor I wasnt talking about a simple 2d vector, i was talking more like an array (maybe 128x128), simulating a wind map image.

So I take it this ISNT what people mean when they talk about "wind maps"? So what exactly is a wind map and how do you use it?
ZealousEngine
ZealousEngine
Also, while on the subject of grass, what would be a good method to cast shadows on my grass objects? I figured since they are so low to the ground, I could just sample the terrain light map, and darken them that way. I WAS goind to sample this texture in the vertex shader (oh that would have been so much faster...), but ive come to learn I have to sample on a per pixel level. I think it will still look good (just be a bit slower).

Is there a better way to 'apply' lightmaps/shadowmaps on your grass? Also im still a little fuzzy on the whole vertex animation/wind map thing :(
ZealousEngine
ZealousEngine
@ lonesock

That link you posted is dead, does anyone else have code for the 'traditional vertex wind animation'? Ive given up on the whole windmap idea, it seems for a windmap you need ps 3.0, or you need to be doing 'pixel displacement grass', which imo looks like crap.

So I think things will look ok if I go with my original plan, to just animated the grass with a simple sin wave, but I still dont understand..

1.) How you give the grass some local chaos (sure I can pass a random value to each grass plain via a uv coord, but what do you DO with it?).

2.) How to alter the sin wave so that the grass doesnt recoil 100% AGAINST the wind.
Kalidor
Kalidor
Quote:
Original post by ZealousEngine
@kalidor I wasnt talking about a simple 2d vector, i was talking more like an array (maybe 128x128), simulating a wind map image.

So I take it this ISNT what people mean when they talk about "wind maps"? So what exactly is a wind map and how do you use it?
I know what you meant but current graphics cards don't have enough registers to pass that many uniform values. What I meant was not passing a single wind vector to be used for all grass vertices, but passing a wind vector for each grass vertex. You do this by using a generic vertex attribute in the same way you would send, for example, per-vertex tangent vectors. So you don't have just a "simple 2d vector," you have a (different) wind vector for each vertex.
Quote:
Original post by ZealousEngine
I WAS goind to sample this texture in the vertex shader (oh that would have been so much faster...)
On current hardware, vertex texture fetches are not as fast as regular texture fetches in a fragment shader. In most cases it is better to pass that data as per-vertex attributes. Vertex textures certainly do have their uses however, and in the future they will certainly be getting faster.

Topic Locked

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

Sign in to reply to this topic.