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