in  vec4 dir;
out vec4 fragColor;
uniform vec4 camera; // xyz- camera origin(LY)  , w - 1/rad(LY)
uniform sampler2D tex0,tex1;
#define  iChannel0 tex0
#define  iChannel1 tex1

vec3 ca=vec3(37. , 29., 86.)*(1./255.);
vec3 cb=vec3(0.  ,146.,214.)*(1./255.);
vec3 cc=vec3(3.  ,141., 50.)*(1./255.);
vec3 cd=vec3(236.,222., 11.)*(1./255.);
vec3 ce=vec3(186., 30., 30.)*(1./255.);

float noise_3( in vec3 x )
{
    vec3 p = floor(x);
    vec3 f = fract(x);
  f = f*f*(3.0-2.0*f);

  vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
  vec2 rg = texture( iChannel0, (uv+0.5)/256.0).yx;
  float v=mix( rg.x, rg.y, f.z );
    return v;
}

const mat3 mx = mat3(0.,0.8,0.6,-0.8,0.36,-0.48,-0.6,-0.48,0.64);
float fbm( vec3 p)
{
  const float scale=16.;
  float f=0.0;
  for (float k=1.;k<5.;k++)
  {
     float k1 = k*scale;
     f += noise_3( k1*p)/k;
     p = mx*p;
  }
  f*=f;
  f=f*f*.05;
  return f;
}

bool RSI(in vec3 ro,in vec3 rd,out vec2 res)
{
  float b = dot(ro,rd);
  float c = dot(ro,ro) - 1.0;
  float d = b*b - c;

  if(d <= 0.0) return false;
  d = sqrt(d);
  res.x=(-b - d);
  res.y=(-b + d);
  return true;
}

bool RSI(in vec3 ro,in vec3 rd,in float scale,out vec2 res)
{
  ro*=scale;
  float b = dot(ro,rd);
  float c = dot(ro,ro) - 1.0;
  float d = b*b - c;
  if(d <= 0.0) return false;
  d = sqrt(d);
  res.x=(-b - d)/scale;
  return true;
}

const float thickness =0.1;
vec4 castray( in vec3 ro, vec3 rd)
{
  const float PI=3.14159265358979;
  vec2 tt;
  if (!RSI(ro,rd,tt)) discard;
  const float dt = 0.01;
  float t=max(tt.x,0.0);
  vec3  acc=vec3(0.0);
  float a=(tt.y-t)*.5;
  for(float i=0.;i<3.;i+=dt  )
  {
   vec3 pos = ro+t*rd;
   float b  = smoothstep(1.0-thickness*2.,1.0-thickness,length(pos));
   if (b>0.0)
   {
    float c1=fbm(pos)*b;
    float c2=c1*c1;
    acc+=vec3(c2*c2,c2*c1,c2);
   }
   t+=dt;
   if (t>tt.y) break;
  }
  t=acc.r*1200.*dt;
  vec3 col;
  if (t<0.25) col=mix(ca,cb,t*4.-0.); else
  if (t< 0.5) col=mix(cb,cc,t*4.-1.); else
  if (t<0.75) col=mix(cc,cd,t*4.-2.); else
  if (t<1.0 ) col=mix(cd,ce,t*4.-3.); else
  col=ce;
  a*=a;
  if (RSI(ro,rd,1./(1.0-thickness),tt))
  {
   vec3 p=ro+rd*tt.x;
   float lon=atan(p.y,p.x);
   float lat=PI/2.-atan(length(p.xy),p.z);
   float x=.5+lon*.5/PI;
   float y=.5+lat/PI;
   col+=texture( iChannel1,vec2(x,y)).rgb;
  }
  return vec4(col,a*.2);
}


void main( )
{
  vec3 ro  =  camera.xyz*camera.w;
  vec3 rd  =  normalize(dir.xyz-camera.xyz);
  vec4 col =  castray(ro,rd);
  // fragColor = vec4( col.rgb, col.a*dir.w );
  fragColor = vec4( col.rgb*(col.a*dir.w), 0. );
}
