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

const float type=7.0; // E0-E7


const float Ibulge = .2; // Bulge Intensity

//const mat3 mx = mat3(0.,0.8,0.6,-0.8,0.36,-0.48,-0.6,-0.48,0.64);
const mat2 m2 = mat2(.8,.6,-.6,.8);

float noise(in vec3 p)
{
  p *= 2.0;
  float res = 0.0;
  float f = 1.0;
  for( int i=0; i<3; i++ )
  {
    p.xy = m2*p.xy;
    p = p.zxy*f+.6;
    f *= 1.15;
    res += sin(p.y+1.3*sin(1.2*p.x)+1.7*sin(1.7*p.z));
  }
  return res / 3.0;
}

float stars( vec3 p )
{
  p = p;
  float f = 1.0;
  float r = 0.0;
  for(int i = 1;i<5;i++)
  {
    r += noise( p*(20.+3.*f) )/f;
    p.xz *= m2;
    f += 1.0;
  }
  return pow(abs(r),8.);
}

// http://adsabs.harvard.edu/abs/1987A&A...175....1M
float bulge(vec3 p,vec3  sbulge)
{
  p/=sbulge;
  float r=length(p);
  float I=pow(r,-0.855)*exp(-pow(r,.25));
  return smoothstep(0.0,.5,.5-r)*(I*Ibulge);
}

bool RSI(in vec3 ro,in vec3 rd,in vec3 scale,out vec2 res)
{
  ro*=scale;
  rd*=scale;
  float k=1.0/length(rd);
  rd *=k;
  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)*k;
  res.y=(-b + d)*k;
  return true;
}


vec4 castray( in vec3 ro, vec3 rd)
{
  vec2 tt1;
  vec3  sbulge = vec3(1.,.9-type*.07,1.); //  bulge size
  bool fb=RSI(ro,rd,2./sbulge,tt1);
  if (fb)
  {
   const float dt = 0.01;
   float abulge  = 0.;
   float astar   = 0.;
   float t = max(0.0,tt1.x),t1=tt1.y;
   for(;;)
   {
     vec3 pos = ro+t*rd;
     float b = bulge(pos,sbulge);
     abulge += b;
     astar  += stars(pos*10.)*b;
     t+=dt;
     if (t>t1) break;
   }
   vec3 col;
   col+=astar*vec3( 1., 1.,.5);    // star light
   col+=abulge*vec3(1.1, .95,.5); // bulge light
   return vec4(col*dt*2.0,clamp(abulge,0.0,1.0));
 }
 return vec4(0.);
}



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.0);
}


