Friday, March 19, 2010

Weird Water

If you look at funky pictures of X-Plane on line, a fair number of them will show incorrect water reflections. I am working on some bug fixes for the reflection code for 950. Bug fixes might not even be the right term. To understand the incorrect reflections, you have to understand what the water code can and cannot do.

The water reflection code renders a reflection based on a flat plane. This limitation comes from the mathematics of the algorithm - a compromise to have water reflections that run at "real-time" speeds. (Real-time is graphics nerd speak for 20-30 fps and not 1-2 fps.)

As it turns out, the Earth is not flat. So we can pick up a number of reflection "bugs", due to the limits of the approximation we are using:

Over very large distances, the flat plane is a bad approximation of a water surface. The flat plane simply can't be "right" everywhere for any large scene. This isn't a bug, it's a ceiling on our maximum quality - a design constraint.

If we have two water surfaces at different elevations (e.g. a river with a dam) we can't have our reflection plane match both. So some scenes may have wrong reflections with multi-level water. This too is a design constraint.

If our reflection plane is at the wrong height or the wrong slope, it is going to produce really weird results. The reflection plane being in the wrong place despite a small scene with one level of water - that'd be a bug.

There is an art to positioning the plane - if we have a large scene (so the round earth means there is no one perfect plane) some locations of the plane will look better than others.

Now one fall-out of all of this is that things are going to look better if water is really flat, which is not always the case (both for some parts of the global scenery with production errors and some third party scenery). Where the water is sloped or contains bumps, we hit the multi-level case where we should not and we face reflection plane placement problems.

Finally, if the scenery mesh contains slanted water, we're really going to be hosed - almost by definition if X-Plane uses a sane water reflection plane, it won't be sloped, and thus this sloped water is going to be unaligned with the reflection plane and produce something that looks really funky.

So my work on 950 is aimed at having X-Plane be less easily fooled by complex and incorrect scenes less often. (Note that X-Plane can't tell the difference between Norway, where we really have water at multiple elevations, and bad input data to MeshTool.)

Even with these fixes, sloped water is still going to look pretty strange (because it is strange). And even with these fixes, multi-level water will still have its reflections approximated at best. But hopefully the visuals from the sim will be less jittery while flying over tricky DSFs.

Not directly related to water rendering, but since you are using GLSL shaders, have you given any thought to baking several octaves of Perlin noise into a little (say 128x128xrgb) texture and modulating the intensity of the fragment color with that?

What this can very easily do is provide "fake" detail at a higher frequency than what's in the main terrain texture. When getting close to some terrain where you normally see single texels blown up to 100x100 on-screen pixels, instead it remains the same base color, but you avoid the "huge monotonous regions of interpolated color" problem. Since you don't need color in the noise texture, just intensity, one texture fetch can get you 3 octaves of noise in the rgb channels.

It doesn't pose a significant load on any modern-ish card; it's just one more sampler request at txCoord.xy*some_frequency, plus a modulation. It can make the terrain look a lot less bland close up.

Raytracing should handle it very well. But yeah, obviously it's an entirely different beast that would require recoding everything. Not to mention the cost of maintaining raytracing structures and raytracing itself.

The water in x-plane is mostly excellent. it tends to fall down only in steep valley rivers. If we assumed that all sloping water is fast moving river water, could the reflections be disabled and replaced with a rapids texture with the direction running downhill, white water doesn't need any reflection. That would solve much of the weird water.

re: using noise for texture detail..the short answer is "yes". We have also looked at using a texture source for detail, as well as using noise sources for more complex modulation effects. There is no question that adding more detail on shader would provide scalability that simply having insanely huge textures wouldn't provide.