// Based On shader : www.shadertoy.com/view/XtXGWM by guil

in  vec4 dir;
out vec4 fragColor;
uniform vec4 camera; // xyz- camera origin(LY)  , w - 1/rad

const float age=5.;
const float scale1=.25;
const float scale2=1.;


vec2 cmul( vec2 a, vec2 b )  { return vec2( a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x ); }
vec2 csqr( vec2 a )  { return vec2( a.x*a.x - a.y*a.y, 2.*a.x*a.y  ); }


float field(in vec3 _p)
{
	float res = 0.;
    vec3 p = _p*5.;
    vec3 c = p;
	for (int i = 0; i < 10; ++i)
    {
     p = abs(p) / dot(p,p) -1.;
     p.yz= csqr(p.yz);
     p.xy= csqr(p.xy);
     res += exp(-age * abs(dot(p,c)));
	}
  return res*scale1;
}




bool RSI(in vec3 ro,in vec3 rd,out vec2 res)
{
  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;
}

vec3 castray( in vec3 ro, vec3 rd )
{
  const float dt = 0.01;
  vec2 tt;
  bool fb=RSI(ro,rd,tt);
  if (fb)
  {
   float t = max(0.0,tt.x);
   vec3 col= vec3(0.);
   for(int n=0;n<100;n++)
   {
    vec3 p=ro+t*rd;
    float fade=clamp(1.0-dot(p,p),0.,1.);
    float c = field(p)*fade;
    col = .97*col+ .03*vec3(c*c*c, c*c, c);
    // t+=dt/(.2+c*c);
    t+=dt/(.2+c);
    if (t>tt.y) break;
   }
   col =  clamp(scale2 *(log(1.+col)),0.,1.);
   return col;
  }
  return vec3(0.);
}


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