|
||||||||||||||||||
Add Forum to Favorites | Send Topic To a Friend | View Forum FAQ | Track this topic |
Last Thread Next Thread ![]() |
| Yann L's water lecture |
|
![]() moggy Member since: 2/11/2003 |
||||
|
|
||||
| Erm, where is it? The link seems to have dissappeared off the GD front page? (Or am I just being blind?) |
||||
|
||||
![]() Agentidd Member since: 2/6/2002 |
||||
|
|
||||
| http://www.andyc.org go to #lectures, its the last one thats just been added. -DD |
||||
|
||||
![]() toucel Member since: 2/16/2003 |
||||
|
|
||||
I too lost this link I had just clicked on it and started reading it. I then left and jumped on my PDA expecting the link to stil be prominently displayed on GameDev. It wasnt. So I found it through Google's cache. Anyway, great discussion Yann (+Trent&RedBeard), I wasnt able to join in although I really wanted to, but regardless, I got a lot out of it. Quick question or two for Yann: I had originally been wondering about how I should approach the reflection texture mapping onto the water, currently I have the reflection texture set up fine and it is projected onto a flat water surface, when altering heights of verts I was unsure of how to adjust the mapping. When I heard your idea of essentially raising a quad of the texture above the surface and seeing where the reflected vectors hit, I almost literally ( However in terms of refraction I was wondering how you would go about snagging a texture map of that which is under the water? Right now I render a reflected image into a texture map, draw the normal scene then the water with the original refection texture. I guess I see the solution as drawing to another texture. But Im thinking that there has to be a better way then another pass (maybe Im just too optimistic). Also, am I correct in my understanding that the refraction texture could be made by rendering from the current position and view (the same that the end scene is rendered from) basically being a reflection of what is in the reflection texture in terms of the view if that makes sense. I hope that all came out clear enough |
||||
|
||||
![]() IronPeter Member since: 4/14/2003 |
||||
|
|
||||
| http://membres.lycos.fr/ylmb/source/solver.cpp Is it really NS equation? It seems like the numerical solution of the Newton equation: d^2 h / dt^2 = "laplas" h. NS equation looks as: 1.) [d/dt+ v*grad] v = F - grad p 2.) div v = 0. To solve NS equation yîu have to find the field of velocities v(x,y). I can not identify v(x,y) in your algo. To solve Newton you have to find scalar h(x,y). The simple Newton equation:
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
float coo[128][128][3];
float vel[128][128];
int q[127][127][4];
void init()
{
int i,j;
for(i=0;i<128;i++)
for(j=0;j<128;j++)
{
coo[i][j][0]=(i-64.0f)/64.0f;
coo[i][j][1]=(j-64.0f)/64.0f;
vel[i][j]=coo[i][j][2]=0.0f;
}
for(i=0;i<127;i++)
for(j=0;j<127;j++)
{
q[i][j][0]=i*128+j;
q[i][j][1]=i*128+j+1;
q[i][j][2]=i*128+j;
q[i][j][3]=i*128+j+128;
}
};
void step()
{
int i,j;
for(i=1;i<127;i++)
for(j=1;j<127;j++)
{
vel[i][j]+=coo[i][j][2]-
(coo[i+1][j][2]+
coo[i-1][j][2]+
coo[i][j+1][2]+
coo[i][j-1][2])*0.25f;
}
for(i=1;i<127;i++)
for(j=1;j<127;j++)
{
coo[i][j][2]-=vel[i][j];
coo[i][j][2]*=0.99f;
}
for(i=0;i<128;i++)
{
coo[i][0][2]=0;
coo[i][127][2]=0;
coo[0][i][2]=0;
coo[127][i][2]=0;
}
}
float a,b,c;
void blup(int x, int y)
{
for(int x1=-10;x1<11;x1++)
for(int y1=-10;y1<11;y1++)
{
float v=100.0f-x1*x1-y1*y1;
if(v<0.0f)v=0.0f;
coo[(x+x1)&127][(y+y1)&127][2]+=v*0.004f;
}
}
void redraw()
{
static char counter;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
glTranslatef (0.0f, 0.0f, -2.0f);
glRotatef(-70,1,0,0);
//glRotatef(10,0,1,0);
glRotatef(c+=0.1f,0,0,1);
if(counter++==0)
blup(rand(),rand());
step();
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,&coo[0][0][0]);
glDrawElements(GL_LINES, 127*127*4, GL_UNSIGNED_INT, &q[0][0][0]);
glutSwapBuffers();
}
float w,h;
void motion(int x, int y)
{
a=300.0f*x/w;
b=300.0f*y/h;
}
void reshape(int width, int height)
{
w=width;
h=height;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(60.0f,(width+0.1f)/(height+0.1f),0.1f,10.0f);
glMatrixMode (GL_MODELVIEW);
glViewport (0, 0, width, height);
}
int main(int argc, char *argv[])
{
int i;
init();
glutInit(&argc, argv);
glutInitWindowSize(800,600);
glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
glutCreateWindow("Peter Popov GLUT");
glutIdleFunc(redraw);
glutDisplayFunc(redraw);
glutMotionFunc(motion);
glutReshapeFunc(reshape);
glutShowWindow();
glClearColor(1.0f,0.5f,0.2f,0.0f);
glutMainLoop();
return 0;
}
PS. Excuse my bad English [edited by - IronPeter on April 24, 2003 4:33:11 PM] [edited by - IronPeter on April 24, 2003 4:33:50 PM] |
||||
|
||||
![]() greeneggs Member since: 4/9/2002 |
||||
|
|
||||
quote: I think you're right. dh/dt = c \Delta(h) + source. Solved with a single Euler step and a 9 point stencil. (Plus the constraint columns can't have negative height.) [edited by - greeneggs on April 24, 2003 6:12:52 PM] |
||||
|
||||
![]() Yann L Moderator Member since: 2/6/2002 From: Breizh |
||||
|
|
||||
quote: Not really. You'll need to somehow distort the refraction texture, and that can only be done, if the image is available in a texture. quote: No, it's not the NSE. I proposed this method as a very simple replacement. Although, if you strip down the NSE by throwing out a set of forces and interactions (which will make turbulences impossible, btw), you basically end up with those equations. |
||||
|
||||
![]() blue_knight Member since: 3/6/2003 From: USA |
||||
|
|
||||
| Assuming that the entire water system is running at the vertex level (reflections/refractions/fresnel/specular/wave motion/interaction/winds), what is the best way to add reflective/refractive bumpmap detail? Using EMBM you can offset your texture coordinates by the bump offset. But 1) how to calculate the offset, 2) how do you get around the bug with the GeForce3 cards where the per-pixel perspective divide doesn't happen when using EMBM?, 3) do you use static tiling bumpmaps or a really hi-res dynamic bumpmap which may be expensive to calculate. Thanks. |
||||
|
||||
![]() RajanSky Banned Member since: 4/26/2002 |
||||
|
||||
| I wrote a little test program to try out Yann's water simulation code which he showed us at the water lecture. His code is very cool and easy to use, but I think maybe I'm doing something silly because the simulation runs fine for about 20 seconds, and then it "blows up"... I wonder if this is some sort of numerical stability problem, but I'm not really sure why it's happening... So I'm posting it here, if anyone might have any ideas as to why this is happening, I'd really appreciate your thoughts... So, here's screenshots below of the program. Every frame, it selects a point and applies a small force there, and then updates the simulation. So the first screenshot, you can see some small waves have appeared, then in the 2nd one, the waves are larger... Then by the 3rd screenshot, something weird happens- slowly, portions of the heightmap just drop to "level water" until the entire water surface becomes flat... And then suddenly the whole water surface jumps to the top of the screen, and there are cylinders which extend along the height of the screen, and then slowly they disappear too... ![]() Anyways.. hmm I'll try to mess around with the parameters, but I've tried a few things and I'm not sure why it "explodes" like that. Does anyone have any ideas on what could be the problem? Thank you very much! Raj Sharma Wildfire Games 0 A.D. Real-time Strategy Game [edited by - Rajansky on April 24, 2003 10:48:24 PM] |
||||
|
||||
![]() moggy Member since: 2/11/2003 |
||||
|
|
||||
| I haven't read the most recent water rendering literature, I haven't had time recently been working my self to death, but I did have a few thoughts. Couldn't you render the surface of water using a constrained net of particles, much like a cloth simulation, but make the constraints between particles a lot softer/looser, and even breakable? This way the water has no fixed volume and won't cause proper "tides" like real water but if you were to drop a ball into it the area directly under the point of impact would "stretch" to accomodate the impact of the ball then, depending on the ball's weight either force it back to the surface with the constraints drawing themselves back together or the constraints 'break' momentarily, the ball falls through and the water 're-heals'. The impact of the ball on the water will cause the correct ripples and the loose effect of the constraints will cause a fairly water-like movement. It may have already been done, I may be speaking rubbish. I dunno, it just seemed like a good idea to me Alex |
||||
|
||||
![]() James Trotter Member since: 1/12/2003 From: Oslo, Norway |
||||
|
|
||||
| That lecture was great, Yann!!! Thanks alot! I wasn't there when you were having the lecture because it was midnight where I live, when you started it... Thanks again!! |
||||
|
||||
![]() Yann L Moderator Member since: 2/6/2002 From: Breizh |
||||
|
|
||||
RajanSky: hmm, I haven't really stress tested the thing, I simply wrote it a couple of hourse before the lecture. It might be some bug in there. Also, keep in mind that the system is very simple, and not really stable. Although it works rather well here, without blowing up. Did you use the default simulation params ? Also, try to not apply a force before every single timestep, that's really a bit much for an Euler integrator. To get it more stable, you can either apply a force every, say, 5 steps or so, or use a better integrator.quote: It was midnight here too... |
||||
|
||||
![]() RajanSky Banned Member since: 4/26/2002 |
||||
|
||||
| Thank you very much Yann! =) I followed your suggestion and now I think the water is stable. Great lecture, by the way, I really enjoyed it Raj Sharma Wildfire Games 0 A.D. Real-time Strategy Game |
||||
|
||||
![]() Dirge Member since: 7/29/2000 From: Dallas, TX, United States |
||||
|
|
||||
| Yann: I wasn't able to make the session, but I have some questions I would really appreciate if you could answer. I'll itemize to make it easier 1) Since you're modifying the vertices of a 2d grid (or a 1d array for efficiency?), if you were using D3D (ffp) or OGL, you'd probably want to store the data in some kind of buffer (vert or index buffer in d3d, vertex array in ogl?). Wouldn't this cause a significant bottleneck since you need to lock and unlock your buffers? Is there a way to accomplish the vertex modifications through a vertex shader? 2) When interacting objects with the 'pool', will you have to use per-vertex/per-triangle collision detection then? Like in the paper where those balls move around when the water is disturbed, are the contact forces completely physically based (or a trick)? 3) Related to 2, what if we wanted to represent a very large body of water (such as an entire lake), how could you implement some kind of culling mechanism on the water? I would think you could just make the entire water area (the lake) into a bunch of different grid tiles (like the voxels in an octree for instance) and frustum cull them? 4) You mentioned you did this just a few hours before the lecture, how can you be so quick! I've found it hard to take direct idea's out of great papers and transfer them to code. Do you have any tips or is it just something you practice? 5) In the dynamic spashing fluids paper it mentions splashs pretty well but I like how the Deep Water Animation and Rendering paper mentions how to implement foam, wave splashs, and spray. Would it be difficult to implement such chaotic behavior into the method you showed? 6) If I wanted to represent a very large body of water (say, an ocean), and have ships realisticlly floating about it, do you think it might be better to use an FFT method (as mentioned in Deep Water Animation and Rendering paper? In other words, is the Navier-Stokes method reliable for an ocean setting or more for pools and relatively calm surfaces? Thanks for any info! Excellent lecture, please do another one real soon! "Love all, trust a few. Do wrong to none." - Shakespeare www.CodeFortress.com |
||||
|
||||
![]() Yann L Moderator Member since: 2/6/2002 From: Breizh |
||||
|
|
||||
| 1) yep, you'll use vertex + index buffers/arrays. There is no way around the vertex buffer update step. You need to somehow plug the results of your water wave model into the vertex position/normals, and you can't compute an NSE in a vertex shader (a simple FFT could perhaps work on a very basic level). But that's not really bad either - if you use a 128² surface (which is already pretty good), then you'll have to update 16384 vertices per frame, a piece of cake with AGP pulled VAR/VOB (in OpenGL, I don't know the D3D equivalent). The index array does not need to be changed. Another possibility are displacement maps, if your hardware supports them. BTW, you can (and should) do the reflection/refraction texcoord distortion in a vertex shader. That way, you don't have to stream texcoords, that reduces the required bandwidth. 2) Contact forces should be completely physically based, ie. representing the effect of buoyancy (sp?). To compute the forces exchanged, you'll need to figure out the contact area between the object and the water surface. There are several different approaches possible for that, it depends on the accuracy you want. 3) You could simply use some standard heightmap LOD system: ROAM, chunked LOD, geomipmapping, just as with terrains. Keep in mind, your water surface is nothing but a kind of constantly deformed hieghtmap terrain. You should also use the NSE (or other physical solver) only for the parts of the heightmap local to the viewer. Using a procedural system for the remaining surface, will save a lot of memory and processing power. 4) A question of practicing it 5) It would be trivial to add. Their method is purely based on the analysis of the resulting heightmap (and slopes). This is wave model independent. 6) Hmm, again, that depends. For ocean settings, I would generally suggest an FFT, or perhaps even noise based approach. If you are in the middle of the ocean, at rough sea, you have absolutely no possibility to see from which direction the waves come - the wave movement is totally chaotic. That's why a noise based approach might even be better suited for this task. An NSE is better suited for surfaces such as pools and calm lakes. You can, however, add an NSE to compute the detail bumpmap on an ocean surface, this will add lots of nice turbulent details. quote: Thanks. I thought it was fun, and if people enjoyed it, I will probably do some more. [edited by - Yann L on April 27, 2003 12:19:20 PM] |
||||
|
||||
All times are ET (US)![]() |
Last Thread Next Thread ![]() |
|