Water rendering in opengl

22,451

The question is quite broad. I'd split it up into separate components and get each working in turn. Hopefully this will help narrow down what those might be, unfortunately I can only offer the higher level discussion you aren't directly after.

The wave simulation (geometry and animation):

A procedural method will give a fixed height for a position and time based on some noise function. A very basic idea is y = sin(x) + cos(z). Some more elaborate examples are in GPUGems.

enter image description here

Just like in the image, you can render geometry by creating a grid, sampling heights (y) at the grid x,y positions and connecting those points with triangles.

If you explicitly store all the heights in a 2D array, you can create some pretty decent looking waves and ripples. The idea here is to update height based on the neighbouring heights, using a few simple rules. For example, each height moves towards the average neighbouring height but also tends towards the equilibrium height equals zero. For this to work well, heights will need a velocity value to give the water momentum.

I found some examples of this kind of dynamic water here:

height_v[i][j] += ((height_west+ height_east + height_south + height_north)/4 - height[i][j]);
height_v[i][j] *= damping;
height[i][j] += height_v[i][j];

Rendering:

Using alpha transparency is a great first step for water. I'd start here until your simulation is running OK. The primary effect you'll want is reflection, so I'll just cover that. Further on you'll want to scale the reflection value using the Fresnel ratio. You may want an absorption effect (like fog) underwater based on distance (see Beer's law, essentially exp(-distance * density)). Getting really fancy, you might want to render the underneath parts of the water with refraction. But back to reflections...

Probably the simplest way to render a planar reflection is stencil reflections, where you'd draw the scene from underneath the water and use the stencil buffer to only affect pixels where you've previously drawn water.

An example is here.

enter image description here

However, this method doesn't work when you have a bumpy surface and the reflection rays are perturbed.

Rather than render the underwater reflection view directly to the screen, you can render it to a texture. Then you have the colour information for the reflection when you render the water. The tricky part is working out where in the texture to sample after calculating the reflection vector.

An example is here.

enter image description here

This uses textures but just for a perfectly planar reflection.

See also: How do I draw a mirror mirroring something in OpenGL?

Share:
22,451
McLovin
Author by

McLovin

Updated on July 09, 2022

Comments

  • McLovin
    McLovin almost 2 years

    I have absolutely no idea how to render water sources (ocean, lake, etc). It's like every tutorial I come across assumes I have the basic knowledge in this subject, and therefore speaks abstractly about the issue, but I don't.

    My goal is to have a height based water level in my terrain.

    I can't find any good article that will help me get started.