Phong illumination models are actually a poor way to represent water surfaces, this example shows how Fresnel based approximations can be combined with view independent environment mapping to try and obtain more realistic results.
Environment mapping using texture information to store the contents of an environment as viewed from an object is a well known technique, unfortunately OpenGL only supports a mapping function which can accomplish this in eye space using glTexGen with GL_SPHERE_MAP for s & t coordinates. This means that if you move the object w.r.t the eye or move the eye then the environment texture must be recomputed and loaded to texture memory, a process which may be computationally expensive. This is described in the EnvMap section of this presentation. It is possible to compute an environment map which exists in world space and compute texture coordinates based on the eye position in world space instead of the object position in eye space. This has the advantage that moving the object or eye does not require that the environment map texture be recomputed. It does impose some restrictions on the scope of environment reflections since due to tiling considerations undesirable results would occur if we try and map a complete sphere, however in the case of an ocean surface or other geometry with the potential to map only a portion of the environment it is possible to generate a world environment texture which is suitable for environment mapping. In this example we environment map an ocean surface which is approximately planar in nature which restricts environment mapping to a hemisphere. Infact the surface sn't quite planar so environment mapping must include more than a hemisphere of information.
An environment map for a planar surface which exists in world space rather than eye space might look something like this:

Many thanks to Nacho Sanz-Pastor for rendering the environment texture used in this example. Here the center of the image represents the zenith of a heliodon surrounding the database and a ring around the map near the border represents the horizon, the information outside the horizon ring is required since our surface isn't planar and a reflected viewing vector may map below the horizon, infact this would be looking back at the sea surface so the environment map introduces a modulated grey reflection of the sky which should look reasonable when mapped to the sea surface, the corners of the texture map are never mapped by reflection vectors.
To apply this textured environment map to scene geometry the normalized view vector to each vertex is reflected through the surface normal of that vertex. This gives a reflection vector which maps to the environment:
In the case of our almost hemispherical environment map we could almost take the x & y vector components as the s & t texture values but this would give very poor resolution towards the horizon and would not extend below the horizon as we require. Instead we need to use the s & t as the azimuth of the texture coordinate from the centre of the texture and then compute the length of this vector to tield a texture coordinate. This mapping is entirely a function of the method used to generate the environment map in the first place and so the mapping in the algorithm should match the mapping in the world space environment map. We assume a linear radial mapping for theta around the zenith and map the reflection vector RV to a texture coordinate in the geoset attribute array Etex thus:
Note the displacement of .5, .5 to translate the hemisphere to the center of the environment texture, the arcsin of the vertical vector component which is used to scale the normalized horizontal component and the multiplication of the value in the range of 0->1 storing 0->M_PI by .25 to scale 0->M_PI*.5 angles to 0->0.5 vector lengths which fits to the texture coordinates 0->1 after translation to the centre of the texture. Infact this multiplication is actually 0.29 to scale the image in compensation for the fact that the horizon lies within the border and values beyond this horizon ring are actually below the horizon but still usefully mapped.
Again this cool bump mapping approach owes a lot to Brian Cabral who recently devised it, and also supplied the code to produce the periodic wave bump images. The principal is that a water surface is infact best treated as a rippled surface which acts like a mirror instead of more conventional illumination algorithms. This surface would reflect incident light according to Fresnels law. Environment mapping maps this reflected light to a surface so if we devise a real-time technique of rendering a Fresnel reflection term to a surface and use this to modulate an environment map we should get some reasonably realistic results. Ideally one would like to modify the portion of the environment mapped as a function of the bump map peturbed surface normal however this may be very costly and so we can approximate the lower frequency surface peturbations with polygons and modulate this environment map with a Fresnel term which includes higher frequency bump mapping to get an approximate result which will look reasonable for many situations. Remember we're trying to improve on existing real-time illumination algorithms which don't well approximate the reflection effect we're looking for so the result we're discussing should at least be an improvement on existing approaches.





The above image sequence illustrates the various effects of the passes as they are drawn to the framebuffer using the bump mapping algorithm. First the per vertex Fresnel is drawn, to which a bump elevation is then added, this is followed by a subtraction of a bump map after texture coordinate peturbation towards the eye to leave a bump mapped Fresnel term. After the Fresnel term is shaded it is multiplied by an environment map texture and finally additional brightness is obtained by adding a further environment mapped term for a bright light source. It is worth noting that the first two passes are combined in a single pass using the GL_ADD texture environment map and the final two passes could be combined by using a suitable texture map and using a glBlendFunc( GL_DST_ALPHA, GL_SRC_ALPHA ) to double the brightness in the framebuffer despite clamping restrictions in the initial Fresnel term shading and texture color.
|
Corporate Office 2011 N. Shoreline Boulevard Mountain View, CA 94043 (650) 960-1980 |
U.S. 1(800) 800-7441 Europe (44) 118-925.75.00 Asia Pacific (81) 3-54.88.18.11 Latin America 1(650) 933.46.37 |
Canada 1(905) 625-4747 Australia/New Zealand (61) 2.9879.95.00 SAARC/India (91) 11.621.13.55 Sub-Saharan Africa (27) 11.884.41.47 |