#version 330 core
out vec4 FragColor; in vec2 vUV; uniform vec2 iResolution; uniform vec2 iMouse; uniform float iTime; 
uniform float uAlpha;
uniform float uSpaceScale;
uniform float uFbmStrength;

// Author: Rigel
// Shader: Mystic Flower
// licence: https://creativecommons.org/licenses/by/4.0/

#define PI 3.141592653589793
#define TWO_PI 6.283185307179586

float hash(vec2 p) { return fract(sin(dot(p,vec2(12.9898,78.2333)))*43758.5453123); }
float noise(vec2 p) { vec2 i = floor(p); vec2 f = fract(p); vec2 u = f*f*(3.0-2.0*f); return mix( mix( hash( i + vec2(0.0,0.0) ), hash( i + vec2(1.0,0.0) ), u.x), mix( hash( i + vec2(0.0,1.0) ), hash( i + vec2(1.0,1.0) ), u.x), u.y); }
float fbm ( vec2 p ) { const mat2 m = mat2(0.8,0.6,-0.6,0.8); float f = 0.0; f += 0.5000*noise ( p ); p*=m*2.02; f += 0.2500*noise ( p ); p*=m*2.04; f += 0.1250*noise ( p ); p*=m*2.03; f += 0.0650*noise ( p ); p*=m*2.01; f /= 0.9375; return f; }
vec3 pal(float domain, vec3 frequency, vec3 phase) { return vec3(0.5) + vec3(0.5) * cos(TWO_PI*(frequency*domain+phase)); }

void mainImage(out vec4 light, in vec2 space) {
  vec2 p = (-0.5 + (space.xy / iResolution.xy)) * vec2(uSpaceScale);
  p.x *= iResolution.x / iResolution.y;
  float a = atan( p.y, abs(p.x) );
  float r = length(p);
  float mouseX = (iMouse.x>0.) ? (iMouse.x-iResolution.x)/iResolution.x : 1.;
  p += vec2(fbm(vec2(a*2.+mouseX*iTime*.1,r*.4-iTime*.3))) * uFbmStrength;
  float cidx = (floor(p.x+2.0) + (floor(p.y+2.0)*4.0)) / 16.0;
  vec3 color = pal(fbm(p*.5), vec3(1.0), vec3(0.4+cidx,0.2+cidx,0.0));
  color *= smoothstep(0.49,0.44, abs(fract(p.x)-0.5));
  color *= smoothstep(0.49,0.44, abs(fract(p.y)-0.5));
  a += fbm(p*0.05);
  float f = abs(cos(a*9.)*sin(a*6.))*.7+.1;
  float ff = smoothstep(f,f+0.05,r);
  color = ff * color + (1.0-ff) * vec3(0.9,0.9,0.7) * (1.8-r);
  color = mix(color,vec3(1.,1.-r*3.,0.0),smoothstep(0.26,0.1+fbm(vec2(r+iTime,a-iTime))*0.06 ,r));
  light = vec4(color,1.0);
}

void main(){ vec2 fragCoord = gl_FragCoord.xy; mainImage(FragColor, fragCoord); FragColor.a *= uAlpha; }
