# Les shader's de Lulu Aspirage de boules fantomatique ```c float length2( vec2 p ) { return sqrt( p.x*p.x + p.y*p.y ); } float length4( vec2 p ) { p = p*p; p = p*p; return pow( p.x + p.y, 1.0/4.0 ); } float length6( vec2 p ) { p = p*p*p; p = p*p; return pow( p.x + p.y, 1.0/6.0 ); } float length8( vec2 p ) { p = p*p; p = p*p; p = p*p; return pow( p.x + p.y, 1.0/0.4 ); } float length8( vec3 p ) { p = p*p; p = p*p; p = p*p; return pow( p.x + p.y + p.z, 1.0/8.0 ); } //------------------------------------------------- float sdCappedCylinder( vec3 p, vec2 h ) { vec2 d = abs(vec2(length(p.xz),p.y)) - h; return min(max(d.x,d.y),0.0) + length(max(d,0.0)); } float sdCappedCylinder4( vec3 p, vec2 h ) { vec2 d = abs(vec2(length4(p.xz),p.y)) - h; return min(max(d.x,d.y),0.0) + length4(max(d,0.0)); } float sdTorus( vec3 p, vec2 t ) { vec2 q = vec2(length(p.xz)-t.x,p.y); return length(q)-t.y; } float sdTorus82( vec3 p, vec2 t ) { vec2 q = vec2(length8(p.xz)-t.x,p.y); return length2(q)-t.y; } float sdSphere( in vec3 p, in float r ) { return length(p)-r; } float sdSphere8( in vec3 p, in float r ) { return length8(p)-r; } //--------------------------------- float map(in vec3 pos) { float d = 1e10; float popox = (iMouse.x / iResolution.x * 2.) - 1.5; float popoy = (iMouse.y / iResolution.y * 2.) - 0.5; // double onion sphere { vec3 q = pos - vec3(popox,popoy,tan(popox * popoy)); d = min( d, sdSphere8( q, 0.4 ) ); } // single onion cylinder { vec3 q = pos - vec3(popox,popoy,tan(popox * popoy)); d = min( d, sdCappedCylinder4( q, vec2(4.4,0.2) ) ); } // single onion torus { vec3 q = pos - vec3(popox,popoy,tan(popox * popoy)); d = min( d, sdTorus82( q, vec2(0.4,4.1) ) ); } // torus { vec3 q = pos - vec3(popox,popoy,tan(popox * popoy)); d = min( d, sdTorus( q.xzy, vec2(0.5,0.2) ) ); } return d; } // http://iquilezles.org/www/articles/normalsSDF/normalsSDF.htm vec3 calcNormal( in vec3 pos ) { const float ep = 0.0001; vec2 e = vec2(1.0,-1.0)*0.5773; return normalize( e.xyy*map( pos + e.xyy*ep ) + e.yyx*map( pos + e.yyx*ep ) - e.yxy*map( pos + e.yxy*ep ) + e.xxx*map( pos + e.xxx*ep ) ); } #define AA 3 void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec3 tot = vec3(0.0); #if AA>1 for( int m=0; m<AA; m++ ) for( int n=0; n<AA; n++ ) { // pixel coordinates vec2 o = vec2(float(m),float(n)) / float(AA) - 0.5; vec2 p = (-iResolution.xy + 2.0*(fragCoord+o))/iResolution.y; #else vec2 p = (-iResolution.xy + 2.0*fragCoord)/iResolution.y; #endif vec3 ro = vec3(0.0,3.0,6.0); vec3 rd = normalize(vec3(p-vec2(0.0,1.0),-2.0)); float t = 5.0; for( int i=0; i<80; i++ ) { vec3 p = ro + t*rd; float h = map(p); if( abs(h)<0.001 || t>10.0 ) break; t += h; } vec3 col = vec3(0.0); if( t<10.0 ) { vec3 pos = ro + t*rd; vec3 nor = calcNormal(pos); vec3 lig = normalize(vec3(1.0,0.8,-0.2)); float dif = clamp(dot(nor,lig),0.0,1.0); float amb = 0.5 + 0.5*nor.y; col = vec3(0.05,0.1,0.15)*amb + vec3(1.00,0.9,0.80)*dif; } col = sqrt( col ); tot += col; #if AA>1 } tot /= float(AA*AA); #endif fragColor = vec4( tot, 1.0 ); } ```