Josip Å tajdohar

First try on water surface fragment code:


                uniform sampler2D tDiffuse;
                uniform float iTime;
                uniform vec2 iResolution;
                varying vec2 sv;
                
                float dot2(vec2 a, vec2 b)
                {
                    return a.x * b.x + a.y * b.y;
                }
                
                float cross2(vec2 a, vec2 b){
                    return a.x * b.y - a.y * b.x;
                }
                
                vec2 rotate(vec2 v, float a) {
                    float s = sin(a);
                    float c = cos(a);
                    mat2 m = mat2(c, -s, s, c);
                    return m * v;
                }
                
                // SDF for a line, found in a comment by valentingalea on https://www.shadertoy.com/view/XllGDs
                float sdf_line(vec2 st, vec2 vert_a, vec2 vert_b){
                    vec2 dvec_ap = st - vert_a;      // Displacement vector from vert_a to our current pixel!
                    vec2 dvec_ab = vert_b - vert_a;  // Displacement vector from vert_a to vert_b
                    vec2 direction = normalize(dvec_ab);  // We find a direction vector, which has unit norm by definition!
                    return cross2(dvec_ap, direction);  // Ah, the mighty cross-norm product!
                }
                
                float hash00(float p)
                {
                    p = fract(p * .1031);
                    p *= p + 33.33;
                    p *= p + p;
                    return fract(p);
                }
                
                float hash2d(vec2 uv)
                {
                    float xhash = cos( uv.x * 37.0 );
                    float yhash = cos( uv.y * 57.0 );
                    return fract( 415.92653 * ( xhash + yhash ) );
                }
                
                float noise(float x)
                {
                    float i = floor(x);
                    float f = fract(x);
                    float u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
                    return mix(hash00(i), hash00(i + 1.0), u);
                }
                
                float sdSphere( vec3 p, float s )
                {
                    return length(p)-s;
                }
                
                float fbmMountains(float pos)
                {
                    float f = 1.2;
                    float a = 0.30;
                    float t = 0.05;
                
                    for(float i = 0.0; i < 8.0; i++)
                    {
                        t += a * noise(f * pos); 
                        f *= 2.0;
                        a *= 0.4;
                    }
                
                    return t;
                }
                
                float fbmSea(vec2 pos)
                {
                    vec2 firstDir = vec2(0.8, 0.2);
                    float angle = 0.5;
                
                    float f = 1.2;
                    float s = 3.2;
                    float a = 1.0;
                    float t = 0.05;
                
                    for(float i = 0.0; i < 4.0; i++)
                    {
                        vec2 dir = rotate(firstDir, i * angle);
                        float sDist = sdf_line(pos, vec2(0.0), dir);
                        t += a * noise(f * (sDist - s * iTime)); 
                        s *= 0.8;
                        f *= 0.7;
                        a *= 0.3;
                    }
                
                    return t;
                }
                
                float sdSea(vec3 pos)
                {
                    // ground
                    float fh = -2.0 + noise(0.5 * (pos.z + 1.8 * iTime));//-2.0;
                    float oneDpos = sdf_line(pos.xz, vec2(0.0), vec2(1.0));
                    fh = -2.0 + noise(0.5 * (oneDpos - 1.8 * iTime));
                    fh = -6.0 + fbmSea(pos.xz);
                    return pos.y - fh;
                }
                
                float map( in vec3 pos)
                {  
                    return sdSea(pos);
                }
                
                #define MAX_STEPS 200; //Dosnt work, rewrite manualy
                #define SURFACE_DIST 0.001;
                #define MAX_DIST 100.0;
                #define MIN_DIST 0.2;
                
                float castRay( in vec3 ro, in vec3 rd)
                {
                    float tmin = MIN_DIST;
                    float tmax = MAX_DIST;
                    float surfDistMin = SURFACE_DIST;
                    
                    float t = tmin;
                    for( int i=0; i<150; i++ )
                    {
                        float h = map( ro+rd*t);
                        //abs increases stability non euklidian mapping after the reymarch steps into
                        //the sdf. the "* t" increases the mistake for farther objects.
                        if( abs(h)tmax ) t=-1.0;
                    
                    return t;
                }
                
                vec3 calcNormal( in vec3 pos)
                {
                    vec2 e = vec2(0.0005, 0.0);
                    return normalize( vec3( 
                        map( pos + e.xyy) - map( pos - e.xyy),
                        map( pos + e.yxy) - map( pos - e.yxy),
                        map( pos + e.yyx) - map( pos - e.yyx) ) );
                }
                
                float getDiffuse(vec3 normal, vec3 lightDir)
                {
                    float diffuseLight = clamp(dot(normal, lightDir), 0. , 1.0);
                
                
                    return diffuseLight;
                }
                
                float getMinnaert(vec3 normal, vec3 lightDir, vec3 viewDir)
                {
                    float diffuseLight = clamp(dot(normal, lightDir), 0. , 1.0);
                
                    float NdotL = max(0.0, dot( normal, lightDir));
                    float NdotV = max(0.0, dot( normal, viewDir));
                
                    float roughness = 0.15;
                
                    float minnaert = saturate( NdotL * pow(NdotL * NdotV, roughness));
                
                
                    return minnaert;
                }
                
                float getSpecular(vec3 pos, vec3 normal, vec3 lightPos, vec3 viewDir)
                {
                    viewDir = normalize(viewDir);
                
                    vec3 reflectDir = reflect(normalize(lightPos - pos), normal);
                
                    return pow(max(dot(-viewDir, reflectDir), 0.0), 32.0);
                }
                
                //Returns the RayDirection for a pixel given the ray origin, the look at vector and a zoom factor.
                vec3 cameraRayDirection(vec2 uv, vec3 rayOrigin, vec3 lookAt, float zoom)
                {
                    vec3 forwardDir = normalize(lookAt - rayOrigin);
                    vec3 rightDir = normalize(cross(vec3(0, 1, 0), forwardDir));
                    vec3 upDir = cross(forwardDir, rightDir);
                    vec3 centerOfScreen = rayOrigin + forwardDir * zoom;
                    vec3 intersectionOfScreen = centerOfScreen + uv.x * rightDir + uv.y * upDir;
                    
                    return intersectionOfScreen - rayOrigin;
                }
                
                vec3 render(vec2 uv)
                {
                    vec3 rayOrigin = vec3(0.0, 0.0, 0.0); 
                    vec3 lookAt = vec3(0, 0, 6.0);
                    vec3 lightDir = normalize(vec3(20.0, 10.0, 5.0));
                    
                    vec3 rayDirection = cameraRayDirection(uv, rayOrigin, lookAt, 1.);
                    
                    float dist = castRay(rayOrigin, rayDirection);
                    vec3 pos = rayOrigin + rayDirection * dist;
                
                    vec3 normal = calcNormal(pos);
                
                    float diffuse = getDiffuse(normal, lightDir);
                    float minnaert = getMinnaert(normal, lightDir, rayDirection);
                    float spec = getSpecular(pos, normal, vec3(130, 20, -300), rayDirection);
                
                    vec3 lightCol = diffuse * vec3(0.02) + minnaert * vec3(0.6) + spec * vec3(0.8);
                    float maxDist = MAX_DIST;
                
                    float stars = pow(hash2d(uv), 800.0);
                
                    vec3 background = vec3(stars);
                
                    //dist negative for to far fields
                    float mountainFBM = 0.5 * fbmMountains(8.0 * uv.x - 15.0);
                
                    float yDisplacement = 0.08;
                    vec3 mountainColor = vec3(0.018);
                    for (float i = 0.0; i < 8.0; i++)
                    {
                        float mountainFBM = 0.3 * fbmMountains(8.0 * uv.x - 15.0 - i * 0.04);
                        float mountainFact = step(mountainFBM, uv.y + yDisplacement + 0.005 * i);
                        mountainColor *= 0.6;
                        background = mix(mountainColor, background, mountainFact);
                    }
                
                    //float moonFact = step(length(uv - vec2(-0.6, 0.35)), 0.020);
                    float moonFact = smoothstep(0.028, 0.020, length(uv - vec2(-0.6, 0.35)));
                    vec3 moonCol = mix(vec3(0.9), vec3(0.1), step(length(uv - vec2(-0.563, 0.35)), 0.04));
                    
                    vec3 moon = mix(background, moonCol, moonFact);
                
                    background = moon;
                    vec3 finalCol = mix(lightCol, background, step(maxDist, dist));
                    return finalCol;
                }
                
                void main()
                {
                    // Normalized pixel coordinates (from 0 to 1)
                    vec2 uv = (sv - 0.5) * iResolution.xy / iResolution.y;
                
                    // Time varying pixel color
                    vec3 col = render(uv);
                
                    //Gama correction
                    col = pow( col, vec3(0.4545));
                    // Output to screen
                    gl_FragColor = vec4(col ,1.0);
                }