version 5
const float IGRID1_SIZE = 1.0/5488.0;
const float IGRID2_SIZE = 1.0/392.0;
const float IGRID3_SIZE = 1.0/28.0;
const float IGRID4_SIZE = 1.0/2.0;

const int   nlayers     = 5;
const float hFadeDistance= 100.0;
const float LinearModelDistance=8000;

uniform vec3 center2cam;
uniform vec3 campos[4];
uniform mat3 geo2local;

uniform mat4 modelproj;

uniform vec3 ll2local;
uniform vec3 Range;  // scr_err*fov/screen_width,amplitude/2, OceanMaxDistance
uniform vec4 origin;   // 2d origin for waves

#ifdef mask
uniform sampler2D maskSampler;
out vec2 texcoord;
uniform vec4 to_tex;
#endif

#ifdef mask1
uniform sampler2D maskSampler1;
out vec2 texcoord1;
uniform vec4 to_tex1;
#endif

uniform sampler2DArray fftWavesSampler;
uniform sampler2DRect  sunSampler;

in  vec3 pos;
out vec2 u; // coordinates in world space used to compute P(u)
out vec3 P; // vector [wave point P(u) in world space,campos]
out float distance2cam;
flat out float sunpower;

/*
_________________________________________________________*/
void main()
{
#if defined(spherical) || defined(linear)
 vec3 lpos = vec3(ll2local.x*pos.x,ll2local.y*pos.y,ll2local.z+pos.z);
#else
 vec3 lpos = geo2local*(pos+center2cam); // pos = geocentric - origin , center2cam = ptn->mx.ov-cam2geo.ov
#endif
 u         = lpos.xy+origin.xy;  // out
 float dist2cam = length(lpos);

#ifdef spherical
    const float Rn  = 6370997.0;
    vec2  sna  = sin(pos.xy);
    vec2  csa  = cos(pos.xy);
    #ifdef intel
      vec2  Ni = inversesqrt(csa*csa+sna*sna);
      csa=csa*Ni;
      sna=sna*Ni;
    #endif
    vec2  cs  = csa*campos[3].xy-sna*campos[2].xy;
    vec2  sn  = sna*campos[3].xy+csa*campos[2].xy;
    vec3  vn  = normalize(vec3(cs.y*cs.x,cs.y*sn.x,sn.y));
    vec3  geo = (Rn*vn-campos[0])+pos.z*vn-campos[1];
    #ifdef linear
      lpos      = mix(lpos,geo2local*geo,clamp( (dist2cam-LinearModelDistance)/LinearModelDistance,0.0,1.0 ));
    #else
      lpos = geo2local*geo; // spherical && !linear
    #endif
#endif // spherical
 lpos.z +=dist2cam*Range.x;
#ifdef mask
 texcoord  = pos.xy*to_tex.xy+to_tex.zw;  // out
#endif
#ifdef mask1
 texcoord1  = pos.xy*to_tex1.xy+to_tex1.zw;  // out
#endif
 u=vec2(u.x*origin.z+u.y*origin.w,u.y*origin.z-u.x*origin.w);
#if defined(linear)
  float fade = max(0.0,1.0-dist2cam*(1.0/hFadeDistance));
  #ifdef mask
    float mask_fade = texture(maskSampler,texcoord).r;
    #ifdef mask1
      mask_fade     = max(mask_fade,texture(maskSampler1,texcoord).r);
    #endif
    fade *= mask_fade;
  #endif
  lpos.z +=(texture(fftWavesSampler, vec3(u * IGRID1_SIZE, 0.0)).x+
            texture(fftWavesSampler, vec3(u * IGRID2_SIZE, 0.0)).y+
            texture(fftWavesSampler, vec3(u * IGRID3_SIZE, 0.0)).z+
            texture(fftWavesSampler, vec3(u * IGRID4_SIZE, 0.0)).w+Range.y)*fade;
  if (nlayers==5)
   lpos.xy+= (texture(fftWavesSampler, vec3(u * IGRID1_SIZE, 3.0)).xy+
              texture(fftWavesSampler, vec3(u * IGRID2_SIZE, 3.0)).zw+
              texture(fftWavesSampler, vec3(u * IGRID3_SIZE, 4.0)).xy+
              texture(fftWavesSampler, vec3(u * IGRID4_SIZE, 4.0)).zw)*fade;
#endif
 gl_Position = modelproj * vec4(lpos, 1.0);
 P=-vec3(lpos.x*origin.z+lpos.y*origin.w,lpos.y*origin.z-lpos.x*origin.w,lpos.z);  // out
 distance2cam=dist2cam;
 sunpower    =texelFetch(sunSampler,ivec2(0,0)).z;
}

