Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

VanKurt

easy/fast oceans

This topic is 5484 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have read a lot of posts, lectures and articles about water rendering but I''m still not sure about what to do. What I want to have is an ocean surrounding my island. Right now this ocean is just a really BIG quad with a moving texture on it. (Looks awfull!!) :-) But I don''t want to spend too much time on this thing and it should run very fast. So things like physically correct 3D Waves, realtime reflections etc. are not neccessary. I thought of this method: Draw 3 layers (Big quads), each one having it''s own moving (tiled) texture (different speed/direction) to create a goodlooking, animated (but flat) water surface. Then add something like a bumpmap to achieve a cool pseudo 3D wave effect. What do you think of this? Is this absolutely stupid? I''m happy about any ideas/suggestions! BTW: I like the water in BF1942. They have a nice *glow* (?) effect. The sun makes the water shine very nicely. (This screenshot doesn''t show this very well)

Share this post


Link to post
Share on other sites
Advertisement
There is no recipe for making oceans, in my opinion it''s more of an artistic project than a technical challenge. Get some photos of beaches and oceans. I think the key points are:

- The way the ocean looks depends on the angle you view it at. From the sand, it''s mostly reflection of the sky. From above, you can see right down to the bottom (near the coast, anyway). Look up ''Fresnel effect'' for more info.

- I''m picturing the Hawaiian islands right now, but I imagine most Pacific islands would be similar - there is always lots of bright and dark green coral in patches around the coast, which you can kind of see through the waves. So your bottom static layer should be heavily burred sand and coral.

- You only really need one moving layer for waves, because only the top of the water really moves. The waves don''t break until they''re fairly near the shore, outside of a few hundred feet they''re just regular swells.

Good luck! Post a screen shot here when you''re done.

Tom

Share this post


Link to post
Share on other sites
how about animated bump maps? to create the waves

thats a really nice effect and in fact you don t translate a single water vertex

you could divide your ocean into a lot of quads
and all quads which lie in a certain radius around your player could be animated with vertex manipulation

sinus wave nothing difficult

you could also create a wave effect towards to beach by getting the ocean->island intersection edges by clipping the island polygons against the ocean top plane
and then create quads with animated wave textures with alpha channel

Share this post


Link to post
Share on other sites
@Basiror
That''s similar to what I was thinking about. Sounds great!
But the problem is that I don''t know anything about bumpmapping...

I found one tut about DOT3 in delphi but that didn''t help me much. I guess you don''t know where to find a "creating-a-cool-ocean-with-bumpmapping" tut???

Thanks, vK

Share this post


Link to post
Share on other sites
um... ocean simulation tutorials are on naturewizard
if you want to get things fast, simply calculate the height of every fourth point (close to the camera & in the view frustum) and interpolate the other points using catmtull patches. you can "increase" your "waves" in radicaling your normals (double x, double z and same y)...
for the lighting simply use arb dot3 bumpmaps. (look at my post for the effect... )

[edited by - 666_1337 on June 17, 2003 10:42:39 AM]

Share this post


Link to post
Share on other sites
The naturewizzard page seems to be about simulating 3d waves only. I think that''s to complicated right now, so I''d rather go for the bumpmap-approach.
The way you did that in your screenshot looks good! Any hints on how you did that? Or some good resource/tutorial?

Thanks a lot!

Share this post


Link to post
Share on other sites
quote:

The way you did that in your screenshot looks good! Any hints on how you did that? Or some good resource/tutorial?

Thanks a lot!


tutorials i don''t have...
but i can give you the source... (I use the way it''s done at naturewizzard o_O)


void oceanWaves :: init(void)
{
texture tex(env->getRootnodePointer()->getImageIOPointer()->loadImage("data/water_1.png"));
waterTexture = env->getRootnodePointer()->getTextureManagerPointer()->addTexture(&tex, GL_TEXTURE_2D, GL_TRUE);

texture _tex(env->getRootnodePointer()->getImageIOPointer()->loadImage("data/water_2.png"));
waterBumpMap = env->getRootnodePointer()->getTextureManagerPointer()->addTexture(&_tex, GL_TEXTURE_2D, GL_TRUE);

OCEAN_GRID_WIDTH = env->getRootnodePointer()->getTerrainPointer()->getWidth()/4;
OCEAN_GRID_HEIGHT = env->getRootnodePointer()->getTerrainPointer()->getHeight()/4;

sea = (float*)malloc(sizeof(float)*OCEAN_GRID_WIDTH*OCEAN_GRID_HEIGHT);
normalMap = (float*)malloc(sizeof(float)*OCEAN_GRID_WIDTH*OCEAN_GRID_HEIGHT*3);

float windSpeed = env->wind.length();
float windDir = atan(env->wind.z/env->wind.x);

fpeak=0.13*GRAVITY_CONSTANT/windSpeed;
max_waves = 250;
for(int i = 0; i < max_waves; i++)
{
WAVE w;
waves.push_back(w);
}

int done = 0;
boost:rogress_display pt(max_waves);

while(done < max_waves)
{
WAVE *w = &waves[done];
float f = genrand();
if(f > 0.0f)
{
w->lambda = 2.0*3.141592*GRAVITY_CONSTANT/(pow( 2.0*3.141592*f,2.0));
w->k = 2.0*3.141592/w->lambda;
w->omega = sqrt(GRAVITY_CONSTANT*w->k);
w->freq = w->omega / (2.0*3.141592);
w->periode = 1.0f/w->freq;
w->direction = (genrand()*2.0f)*3.141592;
w->dirX = cos(w->direction)*0.5f;
w->dirY = sin(w->direction)*0.5f;

float phi0 = 2*genrand()*3.141592;
float a0 = amplitude(w->freq, w->direction - windDir, w->k);

w->amplitude = a0*cos( phi0 );
w->phase = a0*sin( phi0 );
}

if(fabs(w->amplitude) >=0.0001f )
{
done++;
++pt;
}
}
}

#define ax(x) ((x<0)?(x+OCEAN_GRID_WIDTH)(x>=OCEAN_GRID_WIDTH)?(x-OCEAN_GRID_WIDTH):x))
#define ay(y) ((y<0)?(y+OCEAN_GRID_HEIGHT)(y>=OCEAN_GRID_HEIGHT)?(y-OCEAN_GRID_HEIGHT):y))

void oceanWaves :: draw(void)
{
float time = 0.001f * glutGet(GLUT_ELAPSED_TIME);
viewFrustum *vf = env->getRootnodePointer()->getViewFrustumPointer();
glPushMatrix();
glScalef(4.0f, 1.0f, 4.0f);
vf->redefine();

for(int i = 0; i < OCEAN_GRID_WIDTH; i++)
for(int j = 0; j < OCEAN_GRID_HEIGHT; j++)
{
if(! vf->sphereIsInside( point4f((float)((float)OCEAN_GRID_WIDTH*-0.5f + i), 0.0f, (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j)), 2.0f) )
continue;
point4f campos = env->getRootnodePointer()->getCameraPointer()->position;
point4f actpos( ((float)OCEAN_GRID_WIDTH*-0.5f + i)*4.0f, 0.0f, (OCEAN_GRID_HEIGHT*-0.5f + j)*4.0f);
vector4f vec = campos.vectorTo(actpos);
if( vec.length() - 5.0f > env -> getFogDistance())
continue;

float height = 0.0f;
for(int k = 0; k < waves.size(); k++)
height += waves[k].amplitude*sin(waves[k].phase + waves[k].omega * waves[k].freq * (time + waves[k].dirX * i + waves[k].dirY * j ) );
sea[i*OCEAN_GRID_WIDTH + j] = height;
}

for(int i = 0; i < OCEAN_GRID_WIDTH; i++)
for(int j = 0; j < OCEAN_GRID_WIDTH; j++)
{
vector4f v(sea[ax(i+1)*OCEAN_GRID_WIDTH + j] - sea[ax(i-1)*OCEAN_GRID_WIDTH + j],
4.0f,
sea[i*OCEAN_GRID_WIDTH+ay(j+1)] - sea[i*OCEAN_GRID_WIDTH + ay(j-1)]);
v.x *= 4.0f;
v.z *= 4.0f;
v.normalize();

size_t actualindex = (i * OCEAN_GRID_WIDTH + j)*3;
normalMap[actualindex ] = v.x;
normalMap[actualindex+1] = v.y;
normalMap[actualindex+2] = v.z;
}

float mat[4] = {1.0f, 1.0f, 1.0f, 0.2f};
float spec[4] = {1.0f, 1.0f, 1.0f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 96.0f);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

glActiveTextureARB(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.2f * sin(time), 0.2f * cos(time), 0.0f);
glMatrixMode(GL_MODELVIEW);

/*
I need to draw the surface two times because else the wave behind another wave would be blended, and that would result into a bad effect, looking like having no depth test
*/

for(int m = 0; m < 3; m++)
{
for(int i = 0; i < OCEAN_GRID_WIDTH-1; i+=8)
for(int j = 0; j < OCEAN_GRID_HEIGHT-1; j+=8)
{
if(! vf->sphereIsInside( point4f((float)((float)OCEAN_GRID_WIDTH*-0.5f + i + 4.0f), 0.0f, (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j + 4.0f)), 10.0f) )
continue;
point4f campos = env->getRootnodePointer()->getCameraPointer()->position;
point4f actpos( ((float)OCEAN_GRID_WIDTH*-0.5f + i + 4.0f)*4.0f, 0.0f, (OCEAN_GRID_HEIGHT*-0.5f + j + 4.0f)*4.0f);
vector4f vec = campos.vectorTo(actpos);
if( vec.length() - 5.0f*4.0f > env -> getFogDistance())
continue;

for(int k = 0; k < 8; k++)
{
glBegin(GL_TRIANGLE_STRIP);
for(int l = 0; l < 9; l++)
{
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, (float)((float)OCEAN_GRID_WIDTH*-0.5f + i + k), (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j + l));
glNormal3fv( &normalMap[((i+k)*OCEAN_GRID_WIDTH + j+l)*3] );
glVertex3f( (float)((float)OCEAN_GRID_WIDTH*-0.5f + i + k ), sea[(i+k)*OCEAN_GRID_WIDTH + j+l], (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j + l) );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, (float)((float)OCEAN_GRID_WIDTH*-0.5f + i + k + 1), (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j + l));
glNormal3fv( &normalMap[((i+k+1)*OCEAN_GRID_WIDTH + j+l)*3] );
glVertex3f( (float)((float)OCEAN_GRID_WIDTH*-0.5f + i + k + 1), sea[(i+k+1)*OCEAN_GRID_WIDTH + j+l], (float)((float)OCEAN_GRID_HEIGHT*-0.5f + j + l) );
}
glEnd();
}
}
if(m == 0)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glActiveTextureARB(GL_TEXTURE0_ARB);
env->getRootnodePointer()->getTextureManagerPointer()->activateTexture(waterTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
if(m == 1)
{
env->getRootnodePointer()->getTextureManagerPointer()->activateTexture(waterBumpMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB);
}
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);

glPopMatrix();
}

Share this post


Link to post
Share on other sites
note that i don''t use spline interpolation. I (*aiee*) deleted the original source by mistace some days ago and am now rewriting it...

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!