Wasser Shader mit OpenGL
Ein Wasser Shader mit OpenGL
Das gesamte Video wird über Raymarching generiert:
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);
}
Diese SDF habe ich rekursiv aufgerufen, um komplexe Strukturen zu erzeugen. So habe ich eine abstrakte Darstellung von einem Boot generiert.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;
}
Dann habe ich die Oberflächen des Würfels mit einer Funktion kombiniert, um die Quader wellig zu machen. Dabei handelt es sich um Gerstner-Wellen:
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;
}
Zur Dekoration habe ich ein paar Kakteen auf dem merkwürdigen Boot platziert, die wie Segelmasten aussehen sollen. Außerdem habe ich eine simple Datenstruktur definiert, um die einzelnen Objekte in meiner Szene zu speichern, sodass ich die Objekte auch einzeln einfärben und bewegen konnte.
Noch Fragen?