home · browse · search · game entities · user directory · message board · IRC | register

October 27, 2006, 3:53 pm PDT
username  
password  
forgot password?

Popular Resources
  • Half-Life 2 Mod FAQ
  • Valve Hammer Editor
  • Hammer 3.5 beta test
  • Half-Life Utilities
  • game data files
  • ZHLT 2.5.3 custom build
  • Half-Life SDK
  • Feedback
    If you've got any feedback, suggestions, or bugs to report regarding the Collective website, go here!

  • Feedback (301)
  • Newsletter
     
    Enter your email address in the above form to add yourself to the email newsletter list. Click here for more info.

    Hosted Sites
  • Valve ERC
  • Collective
  • TFMapped
  • Spirit of Half-Life
  • Selective Design
  • Pixel Reviews
  • recent articles

    NPC and Item Placement Theory
    17/03/05 11:35pm PST
    Non-Player Character (NPC) and item placement can influence both the gameflow and immersion of a level. This article aims to give some pointers on how to properly place them.
    - Hugh 'Hugh' Lloyd

    Got Props?
    13/03/05 08:32am PST
    A common problem in HL2 mapping is props not showing up in game. This article explains why and offers solutions.
    - Jeff 'Yesukai' Pritchard

    Simulating Randomness
    18/12/04 11:29pm PST
    This article focuses on how to properly simulate random events that should occur at a certain average frequency, or within a certain probability per period of time.
    - Skyler 'Zipster' York

    Adding Single-Player Weapons to Half-Life 2
    15/12/04 06:52pm PST
    Covers the process behind adding weapons to a single-player Half-Life 2 modification.
    - Skyler 'Zipster' York

    Your world in HL2
    06/12/04 12:17am PST
    This article gives tips and advice to anyone wanting to make custom photorealistic textures to be used in Half-Life 2.
    - Oksid

    Hiding in Shadow
    21/08/04 01:11pm PDT
    Describes how to create a function that has monsters disregard you if you are hiding in a certain level of "darkness," which can be set from within map properties.
    - Anders [Wolf] Jenbo (NoBody)

    XSI EXP for Half-Life 2 Tutorial - Camera Control
    23/09/04 12:43am PDT
    A SOFTIMAGE|XSI tutorial explaining all of the camera controls available to you in XSI!
    - Josh Enes

    Bump Mapping in Half-Life
    08/08/04 11:58am PDT
    Details a method of achieving real-time bump mapping in Half-Life, and provides an implementation of the algorithm.
    - Francis 'DeathWish' Woodhouse

    Real-Time "TRON 2.0" Glow For Low-Spec Hardware
    19/06/04 02:06pm PDT
    A sequel to the original "Real-Time 'TRON 2.0' Glow" article, this describes how to implement real-time glow that works on low-spec graphics cards.
    - Francis 'DeathWish' Woodhouse

    Hitboxes and Code
    05/06/04 06:25pm PDT
    How do I make only one part of a monster take damage? Learn about the relationship between model hitboxes and what you can do with them in a characters code.
    - Jonathan 'Teh_Freak' Smith

    Static Water Simulation
    [Sat Dec 07, 2002 / 02:51am PST] Francis 'DeathWish' Woodhouse - comments (33) comments enabled

    Water; it's all around us. Out of a tap, out of the sky - we'd be dead without it. Some may argue that Brits get an unfair slice of the rain pie, and I'd agree there, but without water there would not be life.

    But enough of my ramblings. Water is incredibly hard to represent accurately in games due to its liquid nature and complex physics (indeed, people still don't fully understand the physics of oceans, having to turn to quantum physics to solve a particular problem involving 'freak waves'), but all the same, it is an integral part of many games. I feel that their implementations of water are mostly horribly hacky (Half-Life with its sin(t) 'waves', UT2K3 with its bowls of jelly) and could do with a boost - so, I'm going to explain an algorithm for static water simulation that's been around for a fair amount of time, but hasn't been paid much attention.

    This isn't the best algorithm in the book by far - it has a certain caveat which I'll explain later - but other, better ones involve Fourier transforms, and thus a heck of a lot of computational power which we simply can't afford to spend. At least, not until we're into 20 GHz computers, anyway.

    For this algorithm to work, the water needs to be represented in a grid (size n x m) with each element of the grid being a point on the surface of the water. It also computes the next time step using the last two time steps, and so at least two sets of the grid need to be stored. There are also various constants:

    • d - the distance between adjacent vertices in the grid in both the x and y directions

    • t - the time interval between calculations of the grid - higher for a faster simulation, lower for slower

    • mu (greek letter - a u with an elongated left side) - the viscosity of the fluid - a smaller value allows ripples to exist on the surface for a long time, a larger value makes them diminish faster

    • c - the speed at which ripples travel across the surface

    So, how do we use all these values? Well, there's one large equation which gives the wave height at grid position i, j and time step k (so that the actual position of the vertex being modified is di, dj and the actual time value is kt), which is this:


    (Actually, it gives the height at the next time step, not the current one, but it's the same thing.)

    I know exactly what you're thinking. You're thinking "If I calculate that for every vertex in the grid, it'll slow me down to heck." And you'd be right - if it weren't for some tricks that can be performed. If you carefully examine the equation, you'll notice the first term contains a large amount of multiplication and division purely involving pre-defined constants - so all that has to be done is pre-compute it. The same applies for the second term and the third term, reducing a ton of multiplications, divisions and additions to one multiplication.

    If you apply this function to the grid every frame, you'll find your water will sit there, perfectly still - as it should do. Now, try displacing one of the points by an amount - if you got your constants right the first time, you'll see some ripples form. If you got your constants wrong, you'll see hardly anything happen, or all the vertices in the grid will shoot off exponentially. You see, that's the problem with this algorithm; it has strict conditions as to when it will be stable, and when it will become unstable. These conditions can be expressed in some inequalities, and it's up to you to choose which one to try and satisfy. They are:


    or


    If one of these two conditions is not met, then as mentioned earlier, the vertices will shoot off at an exponential rate, which is definately not how we want our water to behave.

    If, after all this, you're eager to write your own simulation, then good luck. If you want your ripples to 'bounce' off the edges of your grid rather than just dissipating, then always force the edge vertices to stay at a constant height - then it'll behave like a square puddle. Another thing you could do is try to have a variable grid - it'd still be a grid, but you could 'disable' some of the vertices to give it a different shape.

    This concludes this whirlwind tour of a standard static water (and indeed, any fluid you care to mention) simulation. If you want more information on how the equations are derived, then head for chapter 12, fluid simulation, in 'Mathematics for 3D Game Programming & Computer Graphics'.
    article created on Sat Dec 07, 2002 / 02:50am PST
    this item has been viewed 11251 times
    [general / coding]

    Only registered users can post comments. Have you registered yet?

    33 results, 2 pages, viewing page 1.
    prev [ 1 2 ] next

    user comments

    displaying comments of normal or higher rating

    1.

    Skyler 'Zipster' York
    Sat Dec 07, 2002 / 01:18pm PST

      I've always been amazed at how some physicist or computer scientist can actually sit down and come up with such complex equations for simulations of stuff :)

    2.

    Brian 'Fletch' Thomas
    Sat Dec 07, 2002 / 02:48pm PST

      It is times like these when I'm glad I map instead of code.

    3.

    Skyler 'Zipster' York
    Sat Dec 07, 2002 / 04:44pm PST

      Oh, but math is awesome. I'd rather be working with equations than anything else.

    4.

    Skyler 'Zipster' York
    Sat Dec 07, 2002 / 07:59pm PST

      Also, what is the appropiate range for mu? Is it a 0.0 - 1.0 sorta thing, or 0 - 100? Basically, what sort of values should we be plugging in there? While we're at it, what are some appropiate value ranges for all the other variables? I know the stability range for c and t, but we really shouldn't be getting anywhere near where it's unstable.

    5.

    Francis 'DeathWish' Woodhouse
    Sun Dec 08, 2002 / 03:59am PST

      Your appropriate range for mu depends on what your values for t and c are. In my experimentations, I had values of 0.3 for c, 0.1 for mu, 0.5 for d and 0.1 for t, which gave me a nice water-ish effect. If you lower c, you start getting slow rippling sludge, higher values of c get you much more faint, fast ripples. Basically it's all down to experimentation. (By the way, a tip: it's much easier to try to satisfy the inequality with c as its subject, rather than the one with t as its subject - it's a much better indicator of what's wrong if it is going exponential, as it contains a division involving t at the bottom.)

    6.

    Skyler 'Zipster' York
    Sun Dec 08, 2002 / 10:49am PST

      I actually whipped up a little test program myself to test out the values. It used a 25x25 point grid with 10 units spacing (which seems a bit big after your last post). I started out with t at about 0.033 to match the frequency of the rendering (I just assumed t was supposed to be in seconds) and starting playing around with c and mu in the ranges of 100 to 300. It looked fine to me, but I really don't know what to be looking for. Apparently, larger values of mu made the wave stay longer, and smaller values of mu made is dissipate quicker.

    This is the little program I made. If you run the EXE as is, the liquid looks like a big blob of thick slime. You can open up the included source file and recompile it to change values and stuff. And maybe you can modify it a bit to show me the right way to do the simulation :) I mean, if your c is 0.3 and my c is 150, something isn't right on my side :P

    NOTE: It uses Glut (yes I was extremely lazy), so just put GLUT32.DLL (included) in the Windows directory and it shouldn't complain.
    comment modified on Sun Dec 08, 2002 / 10:55am PST

    7.

    Ben 'Mr.Ben' Ives
    Sun Dec 08, 2002 / 10:56am PST

      Each to are own though zipster :), i look at that i'm sure it means something but i'm totally lost.

    8.

    Francis 'DeathWish' Woodhouse
    Sun Dec 08, 2002 / 11:09am PST

      Your large values of c and mu are due to the large d and small t. I had a fairly large t and a small d (5% of yours) and so I had to have smaller values for c and mu. It's perfectly alright - it's just that yours was a much larger body of water than mine, so you have larger values :)

    If people want me to put up the simulation I did, then I'll be happy to do that.

    9.

    neomagus00
    Mon Dec 09, 2002 / 06:12am PST

      yeah, if you've got a sim to compare to zipster's, that'd be cool

    10.

    Daniel 'DAN200' Ratcliffe
    Tue Dec 10, 2002 / 06:29am PST

      I've been trying to do this using vb (as i dont know C++ much and im at college which dosent have it anyway) using a table grid to display the heights as opposed to actually rendering the 3d stuff (which again, i cant do here).

    I'm using the values Deathwish suggested, and im sure i coded it right, but whatever I do the numbers just shoot off really high exponentially (im using a button to simulate causing a ripple in the water, by forcing one of the values to 2). My basic code is as follows...

    term1 = (4 - (8 * ((c ^ 2) * (t ^ 2) / (d ^ 2))) / ((mu * t) + 2))
    term2 = ((mu * t) - 2) / ((mu * t) + 2)
    term3 = (2 * ((c ^ 2) * (t ^ 2) / (d ^ 2))) / ((mu * t) + 2)

    For i = 1 To 5
    For j = 1 To 5
    z(i, j, k + 1) = (term1 * z(i, j, k)) + (term2 * z(i, j, k - 1)) _
    + (term3 * (z(i + 1, j, k) + z(i - 1, j, k) + z(i, j + 1, k) + (z(i, j - 1, k))))
    Next j
    Next i

    The actual array is from 0 to 6 in i and j, so that it will work properly, but only 1 to 5 are calculated on and displayed, but the z values still just keeps getting bigger! Help!

    11.

    Francis 'DeathWish' Woodhouse
    Tue Dec 10, 2002 / 08:18am PST

      In C++, ^ is a bitwise-XOR operator rather than a to-the-power-of operator - I'm guessing it's the same in VB, which is why it's probably messing up. Use Pow() or whatever it is in VB.

    12.

    Skyler 'Zipster' York
    Tue Dec 10, 2002 / 09:37am PST

      Actually, VB does define the ^ operator as the power operator. It's one of the only languages I know about that does.

    If it helps, this is the code I used for my calculations:
    // Pre-calculate coefficients
    cA = (4.0f - ((8.0f*c*c*t*t) / (d*d))) / (mu*t + 2.0f);
    cB = (mu*t - 2.0f) / (mu*t + 2.0f);
    cC = ((2.0f*c*c*t*t) / (d*d)) / (mu*t + 2.0f);

    I looked over yours, and order of operations seems fine. It might be somewhere else in your code, a logic error somewhere.

    13.

    Francis 'DeathWish' Woodhouse
    Tue Dec 10, 2002 / 12:17pm PST

      Okay, I've zipped up my version of the simulation. You can get it here - it contains the source files and the executable.

    In the executable, use the up and down keys to rotate the liquid surface up/down, and use space to randomly displace a point, creating a ripple on the surface. Hold space for what appears like rainfall (lots of displacements).

    Oh, and Zipster - your sim looks like it'd be damn good at generating fractal landscapes. If you watch it after about half a second to a second, it looks like a nice hilly terrain - might be a nice sideline application of this :)

    [edit: the liquid_sim file is now attached and linked to this article]
    comment modified on Fri Dec 13, 2002 / 10:48am PST

    14.

    Chris 'autolycus' Bokitch
    Tue Dec 10, 2002 / 12:51pm PST

      Deathwish, that is the coolest thing I've seen today. :)

    15.

    Skyler 'Zipster' York
    Tue Dec 10, 2002 / 03:32pm PST

     

      Oh, and Zipster - your sim looks like it'd be damn good at generating fractal landscapes. If you watch it after about half a second to a second, it looks like a nice hilly terrain - might be a nice sideline application of this :)

    Hehe, I was actually trying to get it to act like water, but it turned out to be like a slimey substance :P Yours looks like the perfect 'rain falling in lake' sim.

    But hey, I did notice that it looked like some sort of hilly landscape. But I didn't take the idea as far as you did. Maybe I could expand it into a landscape generator for Half-Life maybe? The user would be able to play and pause the simulation to find a good landscape, and then take a "screenshot" to a MAP file... sounds intriguing...
    comment modified on Tue Dec 10, 2002 / 03:33pm PST

    16.

    Francis 'DeathWish' Woodhouse
    Wed Dec 11, 2002 / 07:57am PST

      Another thing I forgot to mention about mine is you can change how hard the 'drop' hits the surface - change the amount that is passed in when the Displace function is called, further down in main.cpp.

    Zipster: I've been thinking about doing the same kind of application myself, except with lots of different fractal terrain generation methods - subdivide and displace, pure random with smoothing, a couple of other methods I forget at the moment. Perhaps we should contact each other on this ;P

    17.

    Daniel 'DAN200' Ratcliffe
    Thu Dec 12, 2002 / 06:06am PST

      Hmm... a little late but I got a 2d version of this working in VB, with an grid of squares that change color according to the z values of the water, its makes some pretty cool disco effects. :)

    18.

    Skyler 'Zipster' York
    Thu Dec 12, 2002 / 09:03am PST

      Disco effects... I like the sound of that :)

    DeathWish: I've been thinking about the idea too, and aside from actual generation methods, I've had a few ideas for neat features. We should contact each other :)

    19.

    Francis 'DeathWish' Woodhouse
    Thu Dec 12, 2002 / 11:23am PST

      For those interested, I'm thinking of making a version of this with environmental cube mapping for reflections. Anyone be interested in it?

    20.

    Michael A. Hobson
    Thu Dec 12, 2002 / 05:02pm PST

      Deathwish:

    I'd be very interested in your cube mapped version.

    Please post it!!

    33 results, 2 pages, viewing page 1.
    prev [ 1 2 ] next

    VERC © 2004. All content copyright its respective owner, all rights reserved.
    script execution time: 0.416708946228 seconds