easy/fast oceans
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)
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
- 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
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
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
@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
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
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]
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]
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!
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!
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(); }
note that i don''t use spline interpolation. I (*aiee*) deleted the original source by mistace some days ago and am now rewriting it...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement