dynamically calculating a "watery" surface

Started by
10 comments, last by Crispy 21 years, 3 months ago
Hello, I admit the subject might be slightly misleading in this case regarding what I''m about to describe: I need to create a lens effect (the eye-lens, not the lens flare) that would distort the viewport so that it would seem like you''re underwater. I figured the best way to do this would be to precalculate a series of texture coordinates, tessellate the screen and overdraw it with the fragments "morphed" into a watery effect. Everything else is doable here for me, except for the math - a little handicap of mine. The effect should be something like, when looking down on a relatively calm water surface, seeing the waves slowly undulate. I''m leaving pretty much to imagination here as I can''t really explain it much better, but if someone does understand what I''m thinking, I''d appreciate some guidance if at all possible. If the above description is too off, I''ll try and come up with a picture thaugh I don''t really know where I''d be able to get one Thanks in advance, Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
Advertisement
do you mean the shadows of the water on the ground?

you could calculate the wave movement in 2d then find the z coordinates of the wave polygons draw the ground
then draw the wave polygons use stencil buffer so you don t get this fancy pixel disortion of coplanar planes and then draw the water surface thats the way id do it

create a luminance alpha texture for waves
that should work pretty well i think
http://www.8ung.at/basiror/theironcross.html
Unfortunately that''s not what I''m after. You''re describing ripple texturing the (underwater) world geometry (for example, any underwater scene in Serious Sam) which I can''t do because of technical reasons - directly related to the game engine. So, instead, I though I''d modulate the frame buffer - draw the world, let the gpu render it, then capture the finalized image from the screen, chop it into pieces, calculate new texture coordinates for the pieces and draw over the previous frame buffer. Everything else is okay here, except for the math I need to modulate the texture coordinates. Basically I want them to follow the pattern of ripples in a (rather) calm body of water (as seen from above) - slightly distorting the final image the user sees and leaving the impression he/she is under water. Old cartoons sometimes have this watery effect alpha mapped over the screen to leave the impression of being under water - I alse want to distort the picture accordingly. Unfortunately I don''t know how to calculate these texture coordinates so that they would look realistic...

Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
What a post to see here! I've just finished a coastal engineering lecture about waves! Still trying to get my head round 5th order approximations, uck!

However, for what you want, a sin wave would probably be a reasonable approximation of a wave in cross-section. Also refraction occurs about the normal of the surface.

Couple of simple definitions (off my uni notes)

wave length = lamda

wave period = T

wave amplitude = a

phase velocity, c = sigma / k
(give the velocity the waves appear to move at)

wave frequency, sigma = 2 * pi / T

Wave number, k = 2 * pi / lamda

c = lamda / T

To get the water surface profile (in section), at time t and distance x from the origin

eta = a * sin(sigma * t - k * x)

if you use something like this to get an angle to deviate the sight line by:

ca = cos(sigma * t - k * x);
ang = arccos( ca );

[edit]I'm being dopey...ang = sigma * t - k * x;

you'll need a scaling factor 'b'...find it by experiment - see what looks good!

delta_x = (depth + eta) * b * tan( ang - angle_of_refraction );

I think this ought to work okay in 1d, realistically waves are made up of many waves comming at different angles & superimposed. To achieve the effect of a wave being at an angle, just do simple triganomitary on the delta_x, which is the distance that the bed should have moved in plan (looking from above). To animate the waves keep incrementing 't'. You could get circular waves by taking 'x' to be the distance from an origin calculated by pythagorus (I can't spell!) ie dist = sqrt(x^2 + y^2); Best thing to do when setting up is to choose a wave speed (say in the order of 0.1-0.2 metres per second for a pond...I'm not exactly sure) and a wave length (for a pond say about 0.1 meters) & get the wave period (T) from that. Assume a wave amplitude (say 0.025 metres in a pond). Calculate 'k' and 'sigma'. Then for each vertex of the tessellation (does this word exist?!) evaluate it's distance from the wave origin & calculate the distance for the texture to move in the direction of the wave movement.

That's all I can be bothered to explain now...I'm guessing slightly about how refraction would work, does someone want to check my calcs?


[edited by - NickB on January 8, 2003 9:14:08 AM]
Wow, NickB, thanks for the reply! I have a big exam coming up tomorrow morning, but I''ll have a more thorough look at it as soon as possible.

Crispy
"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
Crispy (nice nick),

You might look at nVidia''s developer site (developer.nvidia.com). They have some nice demos that demonstrate the use of environment mapping to approximate refraction. I can imagine, as you say, creating a planar mesh that represents your view of the underwater world, and this mesh would be drawn basically at the near view frustum and would cover the entire viewport. Render the underwater world to an environment map and apply that environment map to the mesh. Deform the mesh----or more likely just the normals----to cause the environment map to be deformed. This seems like a natural thing to do with a vertex shader. Check out the nVidia fisheye lens vertex shader for example.



Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
When looking at the bottom of a pool of water from above the surface, you see ripples. However, when you''re in the water, there are no distortions in what you see. Those "ripples" are formed by refraction; this occurs when light passes between two different media. Since the light is in water the whole time when you''re underwater, there''s no refraction, and, hence, no ripple. What you''re trying to do is not physically realistic. Stick your head in your bathtub if you don''t believe me. The only "ripples" you see while under water are changing patterns of light projected on the floor, caused by refraction as the light enters the water through its wavy surface. And an image-space routine cannot do anything that will look at all like that.

If realism isn''t the aim, though, then by all means follow everyone else''s suggestions.
grhodes_at_work: hadn't thought of using enviroment maps...but that's really quite a neat idea!

Crispy: with grhodes_at_work's suggestion to calc the normals you'll need to get the gradient by doing


        // [edit] how the hell did I pass my last maths exam...my differention was slightly wrong!m = a * -k * cos( sigma * t - k * x );// use the gradient to figure out the normal vector in the direction of wave travelsf = sqrt( 1.0f + m * m );// [edit] I also forgot how I'd orientated the axis, DOH! should have checked the logic really// y should alway have a non-zero value & x should have the possibility to become zero// hmmm, I'm now seriously worried about my coastal exams!// flip x & y b/c we want the normal, not the surfacey = 1.0f / sf;x = -m / sf;// x & y are the vector in the direction of wave travel (x in direction & y vertically)// use a 3d transform to align them with the direction the waves// are travelling        


btw. I personally think you ought to deform the vertical coordinates of the surface mesh by the depth of the wave too...

[edited by - NickB on January 8, 2003 9:30:11 AM]


[edited by - NickB on January 8, 2003 12:27:32 PM]
quote:Original post by grhodes_at_work
Crispy (nice nick),


why, thank you kindly

quote:
You might look at nVidia''s developer site (developer.nvidia.com). They have some nice demos that demonstrate the use of environment mapping to approximate refraction.


hmm - must look harder - i''ve browsed the developers'' site quite bit. incidentally, are you referring to opengl or dx (i''ve never dealt with dx - is there a dx developers site at all?)

quote:
I can imagine, as you say, creating a planar mesh that represents your view of the underwater world, and this mesh would be drawn basically at the near view frustum and would cover the entire viewport. Render the underwater world to an environment map and apply that environment map to the mesh. Deform the mesh----or more likely just the normals----to cause the environment map to be deformed. This seems like a natural thing to do with a vertex shader. Check out the nVidia fisheye lens vertex shader for example.


the mesh is drawn in orthogonal view, to fit the viewport, so there''s not too much gain in drawing it very far.

environment mapping is a great idea! i''ll look into it. unfortunately i''m currently running on a tnt2 that doesn''t support vertex programs, but I''m hoping to borrow a gf2 soon.

quote:Original post by TerranFury
When looking at the bottom of a pool of water from above the surface, you see ripples. However, when you''re in the water, there are no distortions in what you see. Those "ripples" are formed by refraction; this occurs when light passes between two different media. Since the light is in water the whole time when you''re underwater, there''s no refraction, and, hence, no ripple. What you''re trying to do is not physically realistic. Stick your head in your bathtub if you don''t believe me. The only "ripples" you see while under water are changing patterns of light projected on the floor, caused by refraction as the light enters the water through its wavy surface. And an image-space routine cannot do anything that will look at all like that.

If realism isn''t the aim, though, then by all means follow everyone else''s suggestions.


I know it doesn''t occur underwater. however, for the sake of first-hand experience, I did stick my head under the water in my lovely cyan bath tub and if you add some motion to the water, you get some deformation - mostly caused by the water getting into your eye - then again it might''ve been the chlorine... anyway - i''m not strictly after realism, but rather a neat effect and my engine is already inefficient enough (well, not really - it''s just that it''s doing quite a lot for a tnt2) to eat up a lot resources and multpiassing any underwater terrain might plummet the fps too low...

quote:Original post by NickB
Crispy: with grhodes_at_work''s suggestion to calc the normals you''ll need to get the gradient by doing


i appreciate your input - it''s been quite a bit helpful. i hope you pass your exams - i still have 3 to come and it''s not necessarily going to be pretty... what''s coastal engineering, though?

Crispy


"Literally, it means that Bob is everything you can think of, but not dead; i.e., Bob is a purple-spotted, yellow-striped bumblebee/dragon/pterodactyl hybrid with a voracious addiction to Twix candy bars, but not dead."- kSquared
quote:
what''s coastal engineering, though?


Coastal process, basically what do waves do when they hit the shore? how can we design structures to be resistant to the impact of waves (the forces involved can be huge)? can we protect the coast line & prevent errosion? also includes off-shore stuff like oil-rigs in the sea & designing them to be resistant to the sea conditions. For example, oil rigs in the north sea need to be able to cope with a 1 in 100 year design wave of 30m height (about 100ft) - learning about waves is kinda important for that.

This topic is closed to new replies.

Advertisement