Right blimey, I didn't expect so much interest.

In answer to J-S and Paul the actual ocean surface rendering is something I 
find particularly interesting. There are many different approaches for this 
(Gerstner, perlin noise, FFT etc), each of which have their own advantages and 
disadvantages. 

An idea I had a while back at the start of this project was to create a nodekit 
designed specifically for ocean surface simulation and rendering. Something 
similar to osgShadow, where various techniques are implemented and can be 
chosen based on the application. So yes it would be interesting to try and tie 
in Paul's work. This type of nodekit I think would be fairly easy to design.

The ocean technique I have implemented is based the FFT technique described by 
Tessendorf in his paper "Simulating Ocean Waves". It is the same algorithm that 
was used in the film Titanic, albeit without the 5.1 billion polygons they 
used. 

The technique produces a tileable height map that can be stitched together to 
form a large expanse of ocean water. Whilst it provides very nice looking 
waves, the fact that it's tileable makes it rather difficult to represent local 
interactions with the waves themselves. Unfortunately wave interactions were 
not a requirement, so I have not taken these into account. However, Tessendorf 
details an approach called IWave that can be used to provide these. 

These tiles can either be pre-computed, or computed in real-time. One 
disadvantage of this technique is the use of Fast Fourier Transforms to 
generate the height maps. FFTs are pretty heavy on the CPU and can be a major 
bottleneck. However, for grid sizes of 128x128 it is still perfectly feasible 
to generate them in real-time. The advantage of this is that you can change 
ocean parameters wind/wave direction, gravity, depth etc on the fly. 
Personally, I decided to pre-compute as these real-time changes were not 
required. 

In my simulation there is no coast line, you are presented with an infinite 
plane of sea. So, I have not considered sea/coast interaction but again this 
can be achieved with the IWave technique. 

The sea surface shader is quite lengthy, largely because it needs to take into 
account both sides of the surface. It uses cube mapping for global reflections 
and a projective texture map for local reflections. I use a series of 
pre-computed normal maps based on the height maps to add additional detail and 
the colour itself is computed based on the angle at which you look at the ocean 
surface. Finally a refraction shader is used if looking upward from under the 
surface. The whitecaps are a bit of a cheat really, there are a couple of 
clever ways of computing these based on the heightmap, but I found that simply 
overlaying a foam texture where the wave peaked above a certain height provided 
the best results in my case.

So, regarding performance, I can happily run a grid of 15x15 ocean tiles 
comprised of 64x64 height values. As the poly count gets pretty high, I use 
GeoMipMapping to reduce the detail of tiles in the distance. Using that with 
the pre-computed height maps I can get 55-60 fps which drops to about 45-50fps 
when I render the scene twice on a 8800 GTS. There are a number of 
optimisations that I haven't made though. The problem with GeoMipMapping of 
course is that detail is relative to the position of the camera. So if you have 
multiple cameras you have to re-compute the geomipmapping for each one. I was 
fortunate as my secondary camera is very close to my primary one so that was 
not an issue.

Aside from the ocean I have:

God-rays - Created by rendering geometrically modelled rays to an FBO and then 
blending them into the scene as a post render.

2D fogging equation - a pre-computed fogging texture is used to simulate the 
underwater fogging based on distance from surface and viewer.

Depth of field - Not exclusive to underwater scenes obviously, but does a nice 
job of creating a watery blur in the distance

Wobbly screen distortion - Post render effect, similar to the effect seen in 
BioShock, that warps the view in a watery fashion. It's not a particularly 
realistic effect but provides a nice underwater visual cue.

Bubbles - implemented using osgParticle

Silt - a volume of tiny particles drifting in the water that tracks with the 
camera position again osgParticle

Seabed Silt - the clouds of sediment created when you kick up the seabed.

Caustics - projective texturing of a series of animated caustic textures

Waving plants - simple vertex shader that applies a sine wave to underwater 
plants to simulate currents.

I think that's about it. With regard to turning this into a nodekit, 
unfortunately I can't do as Robert suggests and release this code as is. The 
simulator itself will not be open source, so I'll have to pull out all the 
relevant bits and present them for review. 

So in the meantime I shall start extracting all the juicy bits. Once that is 
done I'll get back in touch here and discuss with those that are interesting in 
helping.

Thanks for the link to the Ogre library I shall have a look at the approach 
they've taken, seems like a good place to start.


Phew.. long email.


Regards,


Kim.

*****************************************************************************************
To view the terms under which this email is distributed, please go to 
http://www.hull.ac.uk/legal/email_disclaimer.html
*****************************************************************************************
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to