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 edgeFade =0.6;
const float  hgal  = 0.1; // galaxy thickness
const vec3  sgal   = vec3(1.,hgal,1.); //  galaxy size
//------- x=interstellar gas,y=clouds,z=dust ------
const float tilt  = 3.5;
const float scale = 4.5;
const float D0    = 40.;
//----------------------------------
const float Istar=.1;
const float ihI=.8;   // ionized hydrogen intensity
const float Ibulge = 4.; // 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_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;
}

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;
}

vec2 fbm( vec3 p) // x=interstellar gas,y=clouds,z=dust,w=density
{
  vec3 pg = p*1./sgal;
  float r = length(pg.xz);
  float f=0.0;
  float fade=smoothstep(0.0,edgeFade,1.-r)*(1.-abs(pg.y));
  for (float k=1.;k<7.;k++)
  {
     float k1 = k*scale;
     float n1 = noise_3( k1*p)/k;
     f += n1;
     p = mx*p;
  }
  float  Dg=fade*fade*D0;
  return vec2(pow(.2/f,tilt)*Dg,Dg);
}

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

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 tt;
  bool fg=RSI(ro,rd,1./sgal,tt);
  if (fg)
  {
   const float dt = 0.01;
   vec4  alight  = vec4(0.);
   float astar   = 0.;
   float t = max(0.0,tt.x),t1=tt.y;
   for(;;)
   {
     vec3 pos = ro+t*rd;
     vec2  f=fbm(pos);
     float   c1 = f.x,c2=c1*c1;
     astar     += f.x*f.y*stars(pos*7.);
     alight    += vec4(c2*c1,c2,c1,c2*c2);
     t+=dt;
     if (t>t1) break;
   }
   vec3 col=alight.rgb*vec3( 8.0, 4.0,1.8);  // interstellar gas light
   col+=astar*vec3( .8, .8,.4)*Istar;    // star light
   return vec4(col*dt*2.0,min(1.0,alight.b));

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

}


