#define TIME        iTime
#define RESOLUTION  iResolution

const float 
  pi        = acos(-1.)
;

const vec3 
  Units     = vec3(0, 1, 1E-2)
;

mat2 rot(float a) {
  float c=cos(a),s=sin(a);
  return mat2(c,s,-s,c);
}

// License: Unknown, author: Unknown, found: don't remember
float hash2(vec2 co) {
  return fract(sin(dot(co.xy ,vec2(12.9898,58.233))) * 13758.5453);
}


// License: MIT, author: Inigo Quilez, found: https://www.shadertoy.com/view/lsf3WH
//  Value noise function
float vnoise(vec2 p) {
 vec2 i = floor(p);
 vec2 f = fract(p);
    
 vec2 u = f*f*(3.-2.*f);

 float a = hash2(i);
 float b = hash2(i+Units.yx);
 float c = hash2(i+Units.xy);
 float d = hash2(i+Units.yy);
   
 float m0 = mix(a, b, u.x);
 float m1 = mix(c, d, u.x);
 float m2 = mix(m0, m1, u.y);
    
 return m2;
}


// License: MIT, author: Inigo Quilez, found: https://iquilezles.org/articles/fbm/
//  Scales and rotates and aggregates multiple layers of value noise
//  to create something that looks like mountains
vec3 fbm(vec2 p, int ii) {
  vec2 np = p;
  vec2 cp = p;
  float nh = 0.0;
  float na = 1.0;
  float ns = 0.0;
  for (int i = 0; i < ii; ++i) {
    nh += na*vnoise(np);
    np += 123.4;
    np *= 2.11*rot(1.);
    ns += na;
    na *= 0.5;
  }
  
  nh /= ns;

  return vec3(nh);
}

void mainBufferB(out vec4 fragColor, in vec2 fragCoord) {
  vec2 q = fragCoord/RESOLUTION.xy;
  vec2 p = -1. + 2. * q;
  p.x *= RESOLUTION.x/RESOLUTION.y;

  // High resolution FBM
  //  Used for normal computation and raymarching of the detailed mountain
  vec3 col = fbm(p, 6);
  
  fragColor = vec4(col, 1.0);
}