Water Shader with OpenGL
A Water Shader with OpenGL
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;
}
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;
}
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;
}
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.
Feel free to leave your opinion or questions in the comment section below.