Recent

Author Topic: Water wavesimulation - getting the buffer swap right - #some progress#  (Read 4598 times)

DrDoctor

  • Newbie
  • Posts: 3
Hi there,

I'm trying to do a wave simulation like here for Lazarus:

http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
http://www.neilwallis.com/projects/java/water/index.php
http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/the-water-effect-explained-r915
http://www.blitzforum.de/forum/viewtopic.php?t=30764

Although there's some pascal code already I'm somehow stuck on how do swap the buffers right and saving the states of the heightmap (wave strength) in the right way.

Every time I change something I get totally different results.

So I would like to ask you for some advice to get it running...
I attached the source so feel free to play around :-)

Thanks a lot and have a great weekend!
Doc
« Last Edit: April 12, 2016, 09:38:21 pm by DrDoctor »

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
Re: Water wavesimulation - getting the buffer swap right
« Reply #1 on: April 08, 2016, 09:24:14 pm »
Hello DrDoctor,

I am not convinced by the "buffer" method.

Basically, a wave has two components at everypoint: a height (y) and a vertical speed (v). So you can simply have one map of heights and speeds. It is very similar to a vibrating string.

The vertical speed changes depending on the difference of height between a point and its surrounding points. That's the vertical acceleration of the point (a).

So in a first step, you can compute the new speeds:
a = - dy/dx * gravity
v = v * (1 - friction) + a*dt

where dy/dx is the slope, so basically the difference between the height of a pixel and its surrounding
where friction is a value small compared to 1, for example 0.01
where dt is a grain of time, it can be 1 to make things simpler, so you just have to adjust the value of gravity

And in second step, compute the new heights:
y = y + v*dt
here again, you can consider dt = 1 to make things simpler

Regards
Conscience is the debugger of the mind

DrDoctor

  • Newbie
  • Posts: 3
Re: Water wavesimulation - getting the buffer swap right
« Reply #2 on: April 08, 2016, 10:42:26 pm »
Hi Circular,

thanks again for the reply!

I know the buffer method isn't accurate at all unlike your version with all the physics.

On the other hand it was never meant to be.
I just like those neat little graphical effects very much and try to get more into Lazarus by trying to make my own version of such programs.

I could try to use your formulas in the next project!  :)

Doc

DrDoctor

  • Newbie
  • Posts: 3
Re: Water wavesimulation - getting the buffer swap right
« Reply #3 on: April 12, 2016, 09:37:32 pm »
Ok, finally I got it working!  (almost drowned trying...) :D

But I still have some trouble with the variable types of the height fields "h" and "v".
Declaring them as BYTE or WORD to avoid any rounding the image distorts completely atfer the first few waves.

There also seems to be a direct relationship between gravity "g" and "friction".
g=0.2 and friction=0.1 works fine for the moment.

And I'm still not satisfied with my coloration, I think I'm somehow misunderstanding the way colors are calculated in Freepascal using RGB values, alpha and/or these strange $FF1234 numbers...

I added some code to load an image "wasser.jpg" into a TBGRABitmap and read the colors into another heightmap "hCol" to have it disturbed by the waves.
Still, I'm not totally convinced by the result and would like to improve the way any image is put behind...

Anyways, here's the code, have fun with it! :-)

Doc

ArtLogi

  • Full Member
  • ***
  • Posts: 144
gravity and friction as float cousing the code to introduce floating point rounding errors?? Turn them to integers and scale the rest data up accordingly and scale down at the last task if needed to scale down as floating point??? I'm not a pro and didn't read your code so take with grain of salt..
« Last Edit: April 12, 2016, 11:57:12 pm by ArtLogi »

circular

  • Hero Member
  • *****
  • Posts: 3070
    • Personal webpage
The main problem in fact was that the speeds v where computed at the same time as the new heights h. That resulted in an interference between the heights, like a recursive addition.

Here is a version with some improvements:
- two phases for computation of v and h
- optional zoom (see windowZoom constant)
- optimisations using integers (NativeInt) and pointers to go through the pixels
- taking into account diagonals
- color more like the picture provided (using base blue color and adding to go towards white)
- reflection of light on the water (simplified model)
- using AppIdle event to have maximum frame rate
- adding more realistic water drop using sine curve
Conscience is the debugger of the mind

aradeonas

  • Hero Member
  • *****
  • Posts: 824
Ah, that just lovely, good job DrDoctor and Circular , I've been playing with it for the last minutes and it was fun :D
@DrDoctor if you want to participate in contest it will be fun ;)

lainz

  • Hero Member
  • *****
  • Posts: 3380
    • Lainz
Amazing, I like to change the constants and get very different results!

Please as aradeonas said enter the contest
http://forum.lazarus.freepascal.org/index.php/topic,32626.0.html

Maybe you both can add this demo together to participate, or each one with their own wave simulator.