Water Shader with OpenGL

A Water Shader with OpenGL

#OpenGL#C#Projects#Bachelor's Studies#University Studies
In a module in my bachelor's degree, there was an animation project where we had to render a short video with OpenGL. I decided to delve into procedural geometry and raymarching to create a water shader.

Implementation

Raymarching

The entire video is generated using raymarching:

float ray(vec3 ro, vec3 rd, out vec4 col, bool flip){ float t = 0.; float eps = 0.001; uint steps = 100; while(steps>0 && t<FAR_PLANE){ vec3 p = ro + t*rd; float dist = sdTest(p, col, flip); if (dist<eps){ break; } t += dist; steps --; } if (t>= FAR_PLANE){ t = -1.0; } return t; }

Procedural Geometry

Signed distance functions (SDFs) are used to describe the geometry. A simple example is the SDF for a cube: float quader(vec3 p, vec3 b){ vec3 value = abs(p)-b; if(value.x<0.){ value.x = 0.; } if(value.y<0.){ value.y = 0.; } if(value.z<0.){ value.z = 0.; } return length(value); } I called this SDF recursively to create complex structures. This way, I generated an abstract representation of a boat.float recursiveCube(vec3 pos, float edge){ float ret = 10000; vec3 cPos = pos; float cEdge = edge; ret = cube(pos, edge); for(int i=0; i<10; i++){ float mainCube = cube(cPos, cEdge); float sideoffset = cEdge+cEdge*0.75; cPos = cPos-vec3(0,sideoffset,0); cEdge = cEdge*0.75; float smallCube = cube(cPos, cEdge); ret = min(mainCube, min(smallCube, ret)); } return ret; }

Waves

Then I combined the surfaces of the cube with a function to make the cubes wavy. These are Gerstner waves:

vec3 gerstner(vec3 position, float wave_height , float wave_length, float speed, vec2 direction){ vec2 d = normalize(direction); float k = M_PI*2.0f / wave_length; float f = k * (dot(position.xz, d)-uTime*speed); float y = wave_height*sin(f); float x = wave_height * cos(f) * d.x; float z = d.y* wave_height*sin(f); vec3 wave = vec3(x, y, z); return wave; }

Miscellaneous

For decoration, I placed a few cacti on the strange boat, which are supposed to look like masts. I also defined a simple data structure to store the individual objects in my scene, so I could color and move the objects individually.

Result

The (in my opinion, somewhat presentable given the tight timeframe) result is the following video:

Comments

Feel free to leave your opinion or questions in the comment section below.