// @name Petroleum Iris
// @group Oil Slick
// @param uScale "Slick Scale" 2.15 0.35 7.0 0.01
// @param uDrift "Slick Drift" 0.13 -1.5 1.5 0.01
// @param uViscosity "Viscosity" 1.42 0.2 3.5 0.01
// @param uSwirl "Swirl Strength" 0.72 0.0 2.0 0.01
// @param uCells "Marbling Cells" 3.6 0.8 10.0 0.01
// @param uVeins "Black Veins" 0.58 0.0 1.5 0.01
// @param uThickness "Film Thickness" 0.66 0.05 2.0 0.01
// @param uSurfaceWarp "Surface Warp" 0.48 0.0 1.5 0.01
// @group Interference Color
// @param uIridescence "Iridescence" 0.48 0.0 2.0 0.01
// @param uSpectrumWidth "Spectrum Width" 0.82 0.05 2.0 0.01
// @param uBandCount "Interference Bands" 8.0 1.0 24.0 0.1
// @param uHueShift "Hue Shift" 0.04 0.0 1.0 0.01
// @param uSaturation "Color Saturation" 0.78 0.0 1.0 0.01
// @param uBlackLevel "Black Oil Level" 0.012 0.0 0.16 0.001
// @param uRainbowEdge "Rainbow Edges" 0.28 0.0 1.5 0.01
// @group Optics
// @param uGloss "Wet Gloss" 0.88 0.0 1.0 0.01
// @param uFresnel "Fresnel Reflection" 0.58 0.0 3.0 0.01
// @param uHighlight "Studio Highlight" 0.62 0.0 4.0 0.01
// @param uLightAngle "Light Angle" 0.72 -3.14 3.14 0.01
// @param uLightMotion "Light Motion" 0.06 -1.0 1.0 0.01
// @param uExposure "Exposure" 0.88 0.2 3.0 0.01
// @param uVignette "Vignette" 0.42 0.0 1.0 0.01
// @group Audio
// @param uAudioReact "Audio Reactivity" 0.68 0.0 2.0 0.01
// @param uBassSwirl "Bass Swirl" 0.42 0.0 2.0 0.01
// @param uMidBands "Mid Spectrum" 0.48 0.0 2.0 0.01
// @param uTrebleEdges "Treble Edges" 0.58 0.0 2.0 0.01

mat2 irisRot(float a){float s=sin(a),c=cos(a);return mat2(c,-s,s,c);}
float irisHash(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}
float irisNoise(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.0-2.0*f);return mix(mix(irisHash(i),irisHash(i+vec2(1,0)),f.x),mix(irisHash(i+vec2(0,1)),irisHash(i+vec2(1)),f.x),f.y);}
float irisFbm(vec2 p){float v=0.0,a=.5;for(int i=0;i<5;i++){v+=a*irisNoise(p);p=irisRot(.83)*p*2.03+6.1;a*=.5;}return v;}
vec3 hsvIris(vec3 c){vec3 p=abs(fract(c.xxx+vec3(0,.666667,.333333))*6.0-3.0);return c.z*mix(vec3(1),clamp(p-1.0,0.0,1.0),c.y);}

void mainImage(out vec4 fragColor,in vec2 fragCoord){
    vec2 uv=(fragCoord-.5*iResolution.xy)/iResolution.y;float t=iTime;
    float bass=iBass*uAudioReact,mid=iMid*uAudioReact,treble=iTreble*uAudioReact;
    vec2 p=uv*uScale;float drift=t*uDrift/(.3+uViscosity);
    p+=vec2(drift,-drift*.37);float radial=length(p);float angle=atan(p.y,p.x);
    angle+=uSwirl*(irisFbm(p*.7+drift)-.5)*(1.0+bass*uBassSwirl);
    p=irisRot(angle*uSwirl*.12)*p;
    vec2 warp=vec2(irisFbm(p*uCells*.28+vec2(drift,2.7)),irisFbm(p*uCells*.28+vec2(-3.4,-drift)))-.5;
    vec2 q=p+warp*uSurfaceWarp*(1.0+.25*bass);
    float a=irisFbm(q*uCells*.42);float b=irisFbm(q*uCells*.72+warp*2.3-drift*.3);
    float marble=a*.62+b*.38;float vein=pow(abs(sin((marble+warp.x*.3)*18.0)),.35+uVeins*2.0);
    float thickness=(marble+.18*sin(angle*3.0+radial*6.0-drift))*uThickness;
    float bands=thickness*uBandCount*(1.0+mid*uMidBands*.12);
    vec3 spectrum=.5+.5*cos(6.28318*(bands*uSpectrumWidth+uHueShift+vec3(0.0,.33,.67)));
    spectrum=mix(vec3(dot(spectrum,vec3(.299,.587,.114))),spectrum,uSaturation);
    float edge=pow(1.0-vein,3.0);float dark=mix(.08,1.0,vein);
    float e=.008;float dx=irisFbm((q+vec2(e,0))*uCells*.72)-irisFbm((q-vec2(e,0))*uCells*.72);
    float dy=irisFbm((q+vec2(0,e))*uCells*.72)-irisFbm((q-vec2(0,e))*uCells*.72);
    vec3 n=normalize(vec3(-dx/e,-dy/e,1.2));float la=uLightAngle+t*uLightMotion;
    vec3 l=normalize(vec3(cos(la),sin(la),.65)),v=normalize(vec3(-uv*.18,1.0));
    float fres=pow(1.0-max(dot(n,v),0.0),3.0);float spec=pow(max(dot(reflect(-l,n),v),0.0),mix(20.0,170.0,uGloss));
    vec3 col=vec3(uBlackLevel)*dark;
    col+=spectrum*uIridescence*(.012+.14*edge+.07*fres);
    col+=spectrum.brg*uRainbowEdge*pow(edge,4.0)*(.18+treble*uTrebleEdges);
    col+=vec3(.5,.57,.66)*fres*uFresnel*.15+vec3(1.0,.93,.83)*spec*uHighlight;
    col*=uExposure*(1.0+bass*.06);col*=1.0-uVignette*smoothstep(.2,.94,length(uv));
    col=col/(1.0+col*.68);fragColor=vec4(pow(max(col,0.0),vec3(.88)),1.0);
}
