Selected Student Works
This is a small selection of student works from the 2021 class “Advanced Computer Graphics”. The objective was to create an image of an orchid using a single fragment shader. You can see the full homework description if interested.
// credit: @yuuki // orchid: Phalaenopsis Hybrid uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Shady (get it? lol) declarations that I probably ripped off of somewhere (wait a minute...) vec4 mod289(vec4 x){return x-floor(x*(1./289.))*289.;} vec3 mod289(vec3 x){return x-floor(x*(1./289.))*289.;} vec2 mod289(vec2 x){return x-floor(x*(1./289.))*289.;} vec4 permute(vec4 x){return mod289((34.*x+10.)*x);} vec3 permute(vec3 x){return mod289((34.*x+10.)*x);} vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-.85373472095314*r;} float snoise(vec3 v) { const vec2 C=vec2(1./6.,1./3.); const vec4 D=vec4(0.,.5,1.,2.); // First corner vec3 i=floor(v+dot(v,C.yyy)); vec3 x0=v-i+dot(i,C.xxx); // Other corners vec3 g=step(x0.yzx,x0.xyz); vec3 l=1.-g; vec3 i1=min(g.xyz,l.zxy); vec3 i2=max(g.xyz,l.zxy); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1=x0-i1+C.xxx; vec3 x2=x0-i2+C.yyy;// 2.0*C.x = 1/3 = C.y vec3 x3=x0-D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y // Permutations i=mod289(i); vec4 p=permute(permute(permute( i.z+vec4(0.,i1.z,i2.z,1.)) +i.y+vec4(0.,i1.y,i2.y,1.)) +i.x+vec4(0.,i1.x,i2.x,1.)); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_=.142857142857;// 1.0/7.0 vec3 ns=n_*D.wyz-D.xzx; vec4 j=p-49.*floor(p*ns.z*ns.z);// mod(p,7*7) vec4 x_=floor(j*ns.z); vec4 y_=floor(j-7.*x_);// mod(j,N) vec4 x=x_*ns.x+ns.yyyy; vec4 y=y_*ns.x+ns.yyyy; vec4 h=1.-abs(x)-abs(y); vec4 b0=vec4(x.xy,y.xy); vec4 b1=vec4(x.zw,y.zw); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0=floor(b0)*2.+1.; vec4 s1=floor(b1)*2.+1.; vec4 sh=-step(h,vec4(0.)); vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy; vec4 a1=b1.xzyw+s1.xzyw*sh.zzww; vec3 p0=vec3(a0.xy,h.x); vec3 p1=vec3(a0.zw,h.y); vec3 p2=vec3(a1.xy,h.z); vec3 p3=vec3(a1.zw,h.w); //Normalise gradients vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3))); p0*=norm.x; p1*=norm.y; p2*=norm.z; p3*=norm.w; // Mix final noise value vec4 m=max(.5-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.); m=m*m; return 105.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1), dot(p2,x2),dot(p3,x3))); } float snoise(vec2 v){ const vec4 C=vec4(.211324865405187,// (3.0-sqrt(3.0))/6.0 .366025403784439,// 0.5*(sqrt(3.0)-1.0) -.577350269189626,// -1.0 + 2.0 * C.x .024390243902439);// 1.0 / 41.0 // First corner vec2 i=floor(v+dot(v,C.yy)); vec2 x0=v-i+dot(i,C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1=(x0.x>x0.y)?vec2(1.,0.):vec2(0.,1.); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12=x0.xyxy+C.xxzz; x12.xy-=i1; // Permutations i=mod289(i);// Avoid truncation effects in permutation vec3 p=permute(permute(i.y+vec3(0.,i1.y,1.)) +i.x+vec3(0.,i1.x,1.)); vec3 m=max(.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.); m=m*m; m=m*m; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x=2.*fract(p*C.www)-1.; vec3 h=abs(x)-.5; vec3 ox=floor(x+.5); vec3 a0=x-ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m*=1.79284291400159-.85373472095314*(a0*a0+h*h); // Compute final noise value at P vec3 g; g.x=a0.x*x0.x+h.x*x0.y; g.yz=a0.yz*x12.xz+h.yz*x12.yw; return 130.*dot(m,g); } float fbm(vec2 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=snoise(p*scale)/scale; } return f; } float fbm(vec3 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=snoise(p*scale)/scale; } return f; } float turbulence(vec3 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=abs(snoise(p*scale))/scale;} return f; } // End of the god-knows-what declarations // Functions for calculation float noise(vec3 v){ v.xy+=vec2(fbm(v),fbm(vec3(v.xy,v.z+1000.))); return fbm(v)*.35+.45; } // SDs ripped from https://iquilezles.org/ (thanks Inigo Quilez!) float dot2(in vec2 v){return dot(v,v);} float sdEgg(in vec2 p,in float ra,in float rb) { const float k=sqrt(3.); p.x=abs(p.x); float r=ra-rb; return((p.y<0.)?length(vec2(p.x,p.y))-r: (k*(p.x+r)<p.y)?length(vec2(p.x,p.y-k*r)): length(vec2(p.x+r,p.y))-2.*r)-rb; } float sdUnevenCapsule(vec2 p,float r1,float r2,float h) { p.x=abs(p.x); float b=(r1-r2)/h; float a=sqrt(1.-b*b); float k=dot(p,vec2(-b,a)); if(k<0.)return length(p)-r1; if(k>a*h)return length(p-vec2(0.,h))-r2; return dot(p,vec2(a,b))-r1; } float sdEquilateralTriangle(in vec2 p) { const float k=sqrt(3.); p.x=abs(p.x)-1.; p.y=p.y+1./k; if(p.x+k*p.y>0.)p=vec2(p.x-k*p.y,-k*p.x-p.y)/2.; p.x-=clamp(p.x,-2.,0.); return-length(p)*sign(p.y); } float sdPie(in vec2 p,in vec2 c,in float r) { p.x=abs(p.x); float l=length(p)-r; float m=length(p-c*clamp(dot(p,c),0.,r));// c=sin/cos of aperture return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdHeart(in vec2 p) { p.x=abs(p.x); if(p.y+p.x>1.) return sqrt(dot2(p-vec2(.25,.75)))-sqrt(2.)/4.; return sqrt(min(dot2(p-vec2(0.,1.)), dot2(p-.5*max(p.x+p.y,0.))))*sign(p.x-p.y); } float sdVesica(vec2 p,float r,float d) { p=abs(p); float b=sqrt(r*r-d*d); return((p.y-b)*d>p.x*b)?length(p-vec2(0.,b)) :length(p-vec2(-d,0.))-r; } float sdEllipse(in vec2 p,in vec2 ab) { p=abs(p);if(p.x>p.y){p=p.yx;ab=ab.yx;} float l=ab.y*ab.y-ab.x*ab.x; float m=ab.x*p.x/l;float m2=m*m; float n=ab.y*p.y/l;float n2=n*n; float c=(m2+n2-1.)/3.;float c3=c*c*c; float q=c3+m2*n2*2.; float d=c3+m2*n2; float g=m+m*n2; float co; if(d<0.) { float h=acos(q/c3)/3.; float s=cos(h); float t=sin(h)*sqrt(3.); float rx=sqrt(-c*(s+t+2.)+m2); float ry=sqrt(-c*(s-t+2.)+m2); co=(ry+sign(l)*rx+abs(g)/(rx*ry)-m)/2.; } else { float h=2.*m*n*sqrt(d); float s=sign(q+h)*pow(abs(q+h),1./3.); float u=sign(q-h)*pow(abs(q-h),1./3.); float rx=-s-u-c*4.+2.*m2; float ry=(s-u)*sqrt(3.); float rm=sqrt(rx*rx+ry*ry); co=(ry/sqrt(rm-rx)+2.*g/rm-m)/2.; } vec2 r=ab*vec2(co,sqrt(1.-co*co)); return length(r-p)*sign(p.y-r.y); } // Flower patterns adapted from http://verygoodshaderexamples.ga (← very useful website!) vec4 flower_pattern_light(){ vec3 uv=vec3(15.*gl_FragCoord.xy/u_resolution.x-.5,.1*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(1.,.1725,1.,1.),vec4(1.),noise); } vec4 flower_pattern_light_center(){ vec3 uv=vec3(15.*gl_FragCoord.xy/u_resolution.x-.5,.1*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.9725,.8706,.8706,1.),vec4(1.),noise); } vec4 flower_pattern_light_center_pink(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.8157,.5216,.9059,1.),vec4(.9686,.8078,1.,1.),noise); } vec4 flower_pattern_dark(){ vec3 uv=vec3(8.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=.8*turbulence(uv)+.2; return mix(vec4(.5255,0.,.5255,1.),vec4(.7608,.4824,.4824,1.),noise); } vec4 flower_pattern_dark_center(){ vec3 uv=vec3(8.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=.8*turbulence(uv)+.2; return mix(vec4(.2784,.0745,.2784,1.),vec4(.4078,.2392,.2392,1.),noise); } vec4 flower_pattern_yellow(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.2*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.6353,.6588,.2784,1.),vec4(.5216,.1373,.1373,1.),noise); } vec4 flower_pattern_white(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.5*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.9843,.9451,1.,1.),vec4(1.,.9608,.7765,1.),noise); } // Background pattern (it's not very easy to give the colors a natural feel for some reason) vec4 background_pattern(){ vec3 uv=vec3(.5*gl_FragCoord.xy/u_resolution.y-.5,.01*u_time); float noise=pow(noise(uv),4.)*5.; return mix(vec4(.0941,.0353,.0745,.8),vec4(.3255,.0902,.3255,1.),noise); } void main(){ vec2 st=gl_FragCoord.xy/u_resolution.xy; float mask_flower=1.; float mask_flower_edge=0.; float mask_flower_dark=1.; float mask_flower_yellow=0.; float mask_flower_pink=1.; float mask_flower_white=1.; float c1=cos(.2);float s1=sin(.2); mat2 R1=mat2(c1,s1,-s1,c1); float c2=cos(-.2);float s2=sin(-.2); mat2 R2=mat2(c2,s2,-s2,c2); // Generate flower pedals float left_pedal=sdEgg((st.yx-vec2(.5,.3))*R1*2.,.2,.5); float left_pedal_lower=sdEgg((st.yx-vec2(.4,.3))*R1*2.5,.2,.5); float right_pedal=sdEgg((-st.yx+vec2(.5,.7))*R2*2.,.2,.5); float right_pedal_lower=sdEgg((-st.yx+vec2(.4,.7))*R2*2.5,.2,.5); float top_pedal=sdEgg((vec2(st.x,st.y*.7)-vec2(.5,.4))*9.,1.4,.5); mask_flower*=step(.3,left_pedal); mask_flower*=step(.3,left_pedal_lower); mask_flower*=step(.3,right_pedal); mask_flower*=step(.3,right_pedal_lower); mask_flower*=step(.3,top_pedal); // Generate white edges of flower pedals if(left_pedal<.3&&left_pedal>.23)mask_flower_edge+=(left_pedal-.23)*50.*distance(vec2(.5),st.xy); if(right_pedal<.3&&right_pedal>.23)mask_flower_edge+=(right_pedal-.23)*50.*distance(vec2(.5),st.xy); if(left_pedal>.3&&right_pedal>.3){ if(top_pedal<.3&&top_pedal>.23)mask_flower_edge+=(top_pedal-.23)*50.*distance(vec2(.5),st.xy); if(left_pedal_lower<.3&&left_pedal_lower>.23)mask_flower_edge+=(left_pedal_lower-.23)*30.*distance(vec2(.5),st.xy); if(right_pedal_lower<.3&&right_pedal_lower>.23)mask_flower_edge+=(right_pedal_lower-.23)*30.*distance(vec2(.5),st.xy); } // Generate under part of flower float left_rounded_triangle=sdEquilateralTriangle((st.xy/.05-vec2(8,7))*R1); float right_rounded_triangle=sdEquilateralTriangle((st.xy/.05-vec2(12,7))*R2); float lower_rounded_thing=sdPie((st.xy/.4-vec2(1.25,.4)),vec2(1.,.8),.2); float lower_lower_not_rounded_thing=sdVesica((st.xy-vec2(.5,.1))/.7,.1,.2); mask_flower_dark*=step(.4,left_rounded_triangle); mask_flower_dark*=step(.4,right_rounded_triangle); mask_flower_dark*=step(.2,lower_rounded_thing); mask_flower_dark*=step(.2,lower_lower_not_rounded_thing); // Generate center pieces of flower float center_yellow_thing=sdHeart(st.xy/.05-vec2(10,6)); float center_pink_thing=sdEllipse((st.xy-vec2(.5))/.2,vec2(.5,.1)); float center_white_thing=sdUnevenCapsule((st.xy-vec2(.5,.41))/.1,.2,.1,.5); mask_flower_yellow=step(.2,center_yellow_thing); mask_flower_white=step(.2,center_white_thing); if(center_pink_thing<.2) if(center_pink_thing<.0)mask_flower_pink=0.; else mask_flower_pink=(center_pink_thing)*5.; if(center_white_thing<.2)mask_flower_white=1.-distance(vec2(.5,.48),st.xy)*20.; // Draw the elegant flower if(mask_flower_yellow==0.)colour_out=flower_pattern_yellow(); else if(mask_flower_dark==0.)colour_out=mix(flower_pattern_dark(),flower_pattern_dark_center(),.5-distance(vec2(.5,.3),st.xy)*2.); else if(mask_flower==0.){ colour_out=mix(mix(flower_pattern_light(),vec4(1.),mask_flower_edge),flower_pattern_light_center(),distance(vec2(0.),vec2(.5,.4)-distance(vec2(.5),st.xy))/.8); colour_out=mix(flower_pattern_white(),colour_out,mask_flower_white); colour_out=mix(flower_pattern_light_center_pink(),colour_out,mask_flower_pink); } else colour_out=background_pattern(); }
Phalaenopsis Hybrid by @yuuki
// credit: YoshieSuzuki // orchid: Dendrobium uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float M_PI = 3.14159265358979323846; float mix(float x,float y, float a){ return x*(1.0-a)+y*a; } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) : length(p-vec2(-d,-0.008))-r; } float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) { p.x = abs(p.x); float b = (r1-r2)/h; float a = sqrt(1.0-b*b); float k = dot(p,vec2(-b,a)); if( k < 0.0 ) return length(p) - r1; if( k > a*h ) return length(p-vec2(0.0,h)) - r2; return dot(p, vec2(a,b) ) - r1; } float sdOrientedBox( in vec2 p, in vec2 a, in vec2 b, float th ) { float l = length(b-a); vec2 d = (b-a)/l; vec2 q = (p-(a+b)*0.5); q = mat2(d.x,-d.y,d.y,d.x)*q; q = abs(q)-vec2(l,th)*0.5; return length(max(q,0.0)) + min(max(q.x,q.y),0.0); } float sdPie( in vec2 p, in vec2 c, in float r ) { p.x = abs(p.x); float l = length(p) - r; float m = length(p-c*clamp(dot(p,c),0.0,r)); return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdCircle( vec2 p, float r ) { return length(p) - r; } vec3 flag(vec2 uv) { float r = length(uv)*3.0; float a = atan(uv.y,uv.x); float f = abs(cos(a * 3.0)); if(r<=f){ return vec3(0.3,0.0,0.4); }else{ return vec3(1.000,0.914,0.992); } } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 center = vec2(0.5,0.5); float theta = M_PI / 3.0; float mask = 1.0; mask *= step( 0.3, sdVesica( st.xy-vec2(0.50,0.70), 0.1, 0.3 )); mask *= step( 0.0, sdUnevenCapsule( st.xy-vec2(0.50,0.2), 0.1,0.02, 0.3 )); mask *= step( 0.0, sdOrientedBox( st.xy,vec2(0.5,0.0),vec2(0.5,0.1), 0.03 )); colour_out = vec4(mix(0.0, 0.7, exp(-1.0*length(center-st)+0.7)),mix(0.0,0.9, exp(-1.0*length(center-st)+0.25)),1.0,1.000); if(sdOrientedBox( st.xy,vec2(0.5,0.0),vec2(0.5,0.1), 0.03 ) <= 0.0){ colour_out = vec4(0.000,0.495,0.000,1.000); } mat2 rotate = mat2( cos(theta), (-1.0)*sin(theta), sin(theta), cos(theta) ); st = rotate * st; mask *= step( 0.33, sdVesica( st.xy-vec2(0.600,0.000), 0.1, 0.3 )); st = rotate * st; mask *= step( 0.33, sdVesica( st.xy-vec2(0.110,-0.840), 0.1, 0.3 )); theta = M_PI / 6.0; rotate = mat2( cos(theta), (-1.0)*sin(theta), sin(theta), cos(theta) ); st = rotate * st; mask *= step( 0.3, sdVesica( st.xy-vec2(-0.220,-0.900), 0.08, 0.3 )); theta = M_PI / 3.0; rotate = mat2( cos(theta), (-1.0)*sin(theta), sin(theta), cos(theta) ); st = rotate * st; mask *= step( 0.3, sdVesica( st.xy-vec2(-0.630,-0.400), 0.08, 0.3 )); st = gl_FragCoord.xy/u_resolution.xy; theta = M_PI / 1.5; rotate = mat2( cos(theta), (-1.0)*sin(theta), sin(theta), cos(theta) ); st = rotate * st; vec2 reset = gl_FragCoord.xy/u_resolution.xy; if(sdPie( st.xy+vec2(-0.20,0.70),vec2(0.50,0.20),0.15 ) <= 0.0){ st = gl_FragCoord.xy/u_resolution.xy - vec2(0.5,0.5); vec3 ci = flag(st); colour_out = vec4(ci, 1.0); } st = gl_FragCoord.xy/u_resolution.xy; theta = -1.0*M_PI / 1.5; rotate = mat2( cos(theta), (-1.0)*sin(theta), sin(theta), cos(theta) ); st = rotate * st; if(sdPie( st.xy+vec2(0.705,-0.175),vec2(0.5,0.2),0.15 ) <= 0.0){ st = gl_FragCoord.xy/u_resolution.xy - vec2(0.5,0.5); vec3 ci = flag(st); colour_out = vec4(ci, 1.0); } colour_out *= 1.0-mask; }
Dendrobium by YoshieSuzuki
// credit: Chen Chung An (will show up on website) // orchid: Paphiopedilum Purpuratum uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float petal( in vec2 p, in float ra, in float rb, in float curve_x, in float curve_y, in float width_x, in float width_y ) { const float k = sqrt(6.448); p.x = abs(p.x); float r = ra - rb; return ((p.y<0.000) ? length(vec2(p.x, p.y)) - r : (k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) : length(vec2(width_x*pow(p.x,curve_x)+ r,width_y*pow(p.y,curve_y))) - 2.000*r) - rb; } float noise(vec2 p){ return fract(sin(dot(p.xy, vec2(12.988, 78.233))) * 43758.5453); } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float turbulence(vec2 p){ float f = 0.0, scale; for (int i=0; i<4; i++){ scale = pow(pow(3.912,5.116/3.0), float(i)); f += abs(snoise(p * scale)) / scale; } return f; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 bright_spot = vec2(0.430,0.500); vec2 bright_spot_2 = vec2(0.460,0.390); if(petal(vec2(st.x - 0.444, st.y - 0.596), 0.124, -0.268, 0.065, 1.320, 0.159, 1.012) + -0.016 < 0.0 ){ colour_out = vec4( 2.272, 1.584 - sin(sin(st.x*1.648 + -0.716)*sin(st.y*5.260 + -1.812)/0.011), 0.912 , distance(st.x, 2.280*st.y)) ; // top petal } if( max(max(-st.x + 0.392, st.x - 0.432), max(- st.y + -0.300, st.y - 0.428)) < 0.0){ colour_out = vec4(1.368 - st.y,1.432 - st.y,st.y ,0.784)*(st.x + st.y)+st.y*noise(st.xy); // stem } if(pow(((1.200 * (st.x + -0.528))/2.416),2.000) - -0.536 *st.x*st.y + pow(((st.y + -0.584)/1.040),2.000) < 0.724*length(vec2(-0.104*st.y, 0.384*st.x))){ colour_out = vec4(vec3(1.0, st.x > 0.96 - pow(st.y, 2.0) ? 1.008: 1.0 - pow(st.x, 1.960), st.x > 0.96 - pow(st.y, 2.0) ? 1.040: 0.528), st.x*(2.056 + sin((st.y*st.x)/0.002 ))) + (distance(st.xy, vec2(0.300,0.820)) < 0.55 ? -st.x*noise(st.xy):0.0) ; // right petal } if(pow(((2.864 * (st.x + -0.216))/2.120),2.000) - 1.224 *st.x*st.y + pow(((pow(st.y,1.000) + -0.184)/1.040),2.000) + 0.084 < 0.0){ colour_out = vec4(vec3(1.0, st.y < 0.350 ? 1.008: 1.0 - pow(1.0-st.y, 2.264), st.y < 0.35 ? 1.040: 1.0 - pow(1.0-st.y, 1.304)), st.y < 0.35 ? 1.0:st.x*(2.968 + sin(sin(st.x*1.408 + -0.804)*sin(st.y*2.756 + -0.492)/0.003))) + (distance(st.xy, vec2(0.670,0.880)) < 0.55 ? -st.y*noise(st.xy):0.0) ; // right petal } if(pow(((1.000 * (st.x + -0.528))/1.160),2.000) - -0.104 *st.x*st.y + pow(((0.552 * (st.y + -0.356))/1.040),2.000) - 0.024 < 0.0){ colour_out = vec4( vec3(1.25, 0.252+st.y, st.x)*turbulence(st.xy), 1.0 - pow(length(st.xy - vec2(0.550,0.290)),0.416)) ; // bot petal } colour_out += vec4( exp(-length(st.xy - bright_spot) * 45.600)); colour_out += vec4( exp(-length(st.xy - bright_spot_2) * 20.600)); }
Paphiopedilum Purpuratum by Chen Chung An
// credit: Jyhwind // orchid: dendrobium_kingianum uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.110, distance( st.xy, vec2(0.5,0.55) ) ); mask *= step( 0.190, distance( st.xy, vec2(0.5,0.4) ) + distance( st.xy, vec2(0.5,0.5) ) ); mask *= step( 0.342, distance( st.xy, vec2(0.5,0.9) ) + distance( st.xy, vec2(0.5,0.590) ) ); mask *= step( 0.230, distance( st.xy, vec2(0.240,0.710) ) + distance( st.xy, vec2(0.400,0.590) ) ); mask *= step( 0.402, distance( st.xy, vec2(0.130,0.270) ) + distance( st.xy, vec2(0.420,0.500) ) ); mask *= step( 0.230, distance( st.xy, vec2(1.0-0.240,0.710) ) + distance( st.xy, vec2(1.0-0.400,0.590) ) ); mask *= step( 0.402, distance( st.xy, vec2(1.0-0.130,0.270) ) + distance( st.xy, vec2(1.0-0.420,0.500) ) ); colour_out = vec4( 1.0, 1.136*(1.0-distance( st.xy, vec2(0.5, 0.5) )), 1.0, 1.0 ); colour_out *= 1.0-mask; if (distance(st.xy, vec2(0.5, 0.55)) < 0.112 && distance(st.xy, vec2(0.5, 0.55)) > 0.092 && st.y < 0.596) { colour_out = vec4(0.725,0.123,1.000,1.000); } }
Dendrobium Kingianum by Jyhwind
// credit: aoi (will show up on website) // orchid: Phalaenopsis lindenii uniform vec2 u_resolution; float petalDown(in vec2 pos) { pos = pos + vec2(0.0, -0.05); float a = atan(pos.x * 1.4, pos.y + 0.2) / 3.14159 * 1.65; float d = length(pos) - mix(0.15, 1.5, abs(fract(a) - 0.5)); return d; } float petalMiddle(in vec2 pos) { pos = abs(pos) * 2.0; pos = vec2(abs(pos.x - pos.y), 1.0 - pos.x - pos.y) / sqrt(2.0); float he = sin(1.0); he = (0.001 + abs(he)) * ((he >= 0.0) ? 1.0 : -1.0); float p = (he - pos.y - 0.25 / he) / (6.0 * he); float q = pos.x / (he * he * 16.0); float h = q * q - p * p * p; float x; if (h > 0.0) { float r = sqrt(h); x = pow(q + r, 1.0 / 3.0) - pow(abs(q - r), 1.0 / 3.0) * sign(r - q); } else { float r = sqrt(p); x = 2.0 * r * cos(acos(q / (p * r)) / 3.0); } x = min(x, sqrt(2.0) / 2.0); vec2 z = vec2(x, he * (1.0 - 2.0 * x * x)) - pos; return length(z) * sign(z.y) - 0.4; } float petalUp(in vec2 p) { const float k = sqrt(3.0); p.x = abs(p.x); p.y += 0.45; float ra = 0.3; float rb = ra * (0.1); float r = ra - rb; return ((p.y<0.0) ? length(vec2(p.x, p.y)) - r: (k * (p.x + r) <p.y) ? length(vec2(p.x, p.y - k * r)): length(vec2(p.x + r, p.y)) - 2.0 * r) - rb; } float star(in vec2 p) { p.y += 0.1; float r = 0.15; float n = 3.0 + mod(floor(2.0), 9.0); float m = 3.0 + fract(2.0) * fract(2.0) * (n - 2.0); float an = 3.141593 / float(n); float en = 3.141593 / m; vec2 acs = vec2(cos(an), sin(an)); vec2 ecs = vec2(cos(en), sin(en)); float bn = mod(atan(p.x, p.y), 2.0 * an) - an; p = length(p) * vec2(cos(bn), abs(sin(bn))); p -= r * acs; p += ecs * clamp(-dot(p, ecs), 0.0, r * acs.y / ecs.y); return length(p) * sign(p.x); } float sdUnion(float d1, float d2, float d3) { return min(min(d1, d2), d3); } float sdDifference(float d1, float d2) { return max(d1, -d2); } void main() { vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution.xy) / u_resolution.y; float p1 = petalDown(p); float p2 = petalMiddle(p); float p3 = petalUp(p); float p4 = star(p); float d = sdDifference(sdUnion(p1, p2, p3), p4); vec3 col = vec3(0.7, p.y * 0.47, 1.0) - sign(d); col *= 1.1 - exp(-2.0 * abs(d)); col *= 0.8 + 0.2 * cos(120.0 * abs(d)); col = mix(col, vec3(0.79, 0.67, 0.82), 1.0 - smoothstep(0.0, 0.01, abs(d))); colour_out = vec4(col, 0.9); }
Phalaenopsis Lindenii by aoi
// Name: Niku-Mochi // Orchid: eastern Queen of Sheba Orhicd (Scientific name: Thelymitra speciosa) // Description: Thelymitra speciosa, commonly called the eastern Queen of Sheba, is a species of orchid in the family Orchidaceae and endemic to the south-west of Western Australia. (https://en.wikipedia.org/wiki/Thelymitra_speciosa, accessed on 2021.12.05) // Reference photos: http://orchidswa.com.au/thelymitra-sun-orchids/queen-of-sheba/ uniform vec2 u_resolution; const float pi = 3.14159; // SDF function for the intersection of two mirror-symmetric circles // Input: p (position), r (radius), d (distance btw center of circle and axis of symmetry). float sdf_vesica(vec2 p, float r, float d){ p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d > p.x*b) ? (length(p-vec2(0.0,b)) * sign(d)) : (length(p-vec2(-d,0.0)) - r); } // SDF function for drawing circles float sdf_circle(vec2 p, float r){ return length(p) - r; } // Rotation and translation of sdf_vesica() // Input: p, r, d (as sdf_vesica()), theta (rotated angle), t (translation distance) float sdf_transform(vec2 p, float r, float d, float theta, vec2 t){ float c = cos(theta), s = sin(theta); t = mat2(c, s, -s, c) * t; mat3 H = mat3(vec3(c, s, 0.0), vec3(-s, c, 0.0), vec3(vec2(t), 1.0)); p = (inverse(H) * vec3(p,1.0)).xy; return sdf_vesica(p, r, d); } // SDF function for drawing petals // Input: p, r, d (as sdf_vesica()), theta (3 rotated angles), t (3 distances) float sdf_petals(vec2 p, float r, float d, vec3 theta, vec3 t){ float d1 = sdf_transform(p, r, d, theta.x, vec2(0.0,t.x)); float d2 = sdf_transform(p, r, d, theta.y, vec2(0.0,t.y)); float d3 = sdf_transform(p, r, d, theta.z, vec2(0.0,t.z)); return min(min(d1,d2),d3); } // SDF function for drawing stamens (or pistils?) float sdf_stamens(vec2 p){ float d1 = sdf_circle(p+vec2(0.00,-0.01), 0.04); float d2 = sdf_circle(p+vec2(-0.05,-0.055), 0.03); float d3 = sdf_circle(p+vec2(0.04,-0.05), 0.027); return min(min(d1,d2),d3); } // Function for differently colored edges of petals // Input: c (petal color), edge_c (edge color), sdf_d1, sdf_d2 (petals set 1 and set 2) vec3 petal_edge(vec3 c, vec3 edge_c, float sdf_d1, float sdf_d2){ vec3 out_c = c; if (sign(sdf_d1)<=0.0){ out_c = mix(c, edge_c, smoothstep(0.03,0.00,abs(sdf_d1))); } else if (sign(sdf_d1)>0.0 && sign(sdf_d2)<=0.0){ out_c = mix(c, edge_c, smoothstep(0.10,0.00,abs(sdf_d2))); } else{ out_c = out_c; } return out_c; } // Random 2D function vec2 rand_2(vec2 p) { const highp float seed = 12.9898; highp float a = seed, b = 78.233, c = 43758.5453, d = 269.5, e = 183.3; highp float dt_1 = dot(p, vec2(a,b)); return fract(sin(vec2(dt_1,dt_1)) * c); } // Reference: Cellular Noise. https://thebookofshaders.com/12/. Accessed on 2021.12.05. float noise(vec2 p){ // Tiling vec2 int_p = floor(p), frac_p = fract(p); // Minimum distance float min_dist = 0.425; for (int j=-1; j<=1; j++){ for (int i=-1; i<=1; i++ ){ // Random offset vec2 offset = rand_2(int_p + vec2(float(i),float(j))); offset = 0.6 + 0.45 * sin(0.98*offset+100.0); // Position of the cell vec2 pos = vec2(float(i),float(j)) + offset - frac_p; min_dist = min(min_dist, min_dist*length(pos)); } } return min_dist; } void main(){ // Define color vec3 dark_magenta = vec3(0.55,0.00,0.55); vec3 green_yellow = vec3(0.78,0.85,0.68); vec3 dark_orange = vec3(0.745,0.306,0.125); vec3 yellow = vec3(0.953,0.878,0.231); vec3 black_brown = vec3(0.271,0.196,0.176); vec3 purple = vec3(0.750,0.212,0.500); // Call sdf function to create petals and stamens vec2 p = gl_FragCoord.xy / u_resolution.xy; p -= vec2(0.5); float dist = 0.27; float ra = max(0.36, dist); // Two sets of petals. Each will be applied different patterns. // Adopt different rotation angles to make the orchid more 'natrual'. float d_petals_1 = sdf_petals(p, ra, dist, vec3(1.10, 3.05, 4.88)*pi/3.0, vec3(0.22,0.19,0.21)); float d_petals_2 = sdf_petals(p, ra, dist, vec3(-0.10, 2.05, 3.95)*pi/3.0, vec3(0.20,0.20,0.20)); // Stamens float d_stamens_1 = sdf_circle(p+vec2(0.000,0.025), 0.05); float d_stamens_2 = sdf_stamens(p); // Outline of the orchid float d_petals = min(d_petals_1,d_petals_2);//union of 2 petal sets vec3 col_orc = mix(dark_magenta, green_yellow, step(0.0,d_petals)); // Pattern 1 of petals (broad reddish edges) col_orc = petal_edge(col_orc, dark_orange, d_petals_1, d_petals_2); // Pattern 2 of petals (dark spots) by calling noise func p += vec2(0.5); p *= 15.0; float d_spots = max(noise(p)-0.06, d_petals);//intersection of spots and petals col_orc = mix(black_brown, col_orc, step(0.0,d_spots)); // Draw stamens col_orc = mix(purple, col_orc, step(0.0,d_stamens_1)); col_orc = mix(yellow, col_orc, step(0.0,d_stamens_2)); // Output colour_out = vec4(col_orc,1.0); }
Thelymitra Speciosa (Eastern Queen of Sheba
Orchid) by Niku-Mochi
// credit: @amycqx // orchid: Cymbidium cv orchid @Geoff McKay // https://www.flickr.com/photos/129472387@N07/49368814152/in/photostream/ uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float sdSegment( in vec2 p, in vec2 a, in vec2 b ) { vec2 pa = p-a, ba = b-a; float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); return length( pa - ba*h ); } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) : length(p-vec2(-d,0.0))-r; } float sdVesica1(vec2 p,float r, float d,float rotate){ float s=sin(-rotate),c=cos(-rotate); vec2 q; q.x=p.x*c-p.y*s; q.y=p.y*c+p.x*s; q.y-=sqrt(r*r-d*d); return sdVesica(q,r,d); } float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) { p.x = abs(p.x); float b = (r1-r2)/h; float a = sqrt(1.0-b*b); float k = dot(p,vec2(-b,a)); if( k < 0.0 ) return length(p) - r1; if( k > a*h ) return length(p-vec2(0.0,h)) - r2; return dot(p, vec2(a,b) ) - r1; } float sdUnevenCapsule1(vec2 p,vec2 pa, vec2 pb,float ra, float rb){ pb-=pa; float h=sqrt(dot(pb,pb)); p-=pa; vec2 q=vec2(dot(p,vec2(pb.y,-pb.x)),dot(p,pb))/h; return sdUnevenCapsule(q,ra,rb,h); } float sdRoundedBox( in vec2 p, in vec2 b, in vec4 r ) { r.xy = (p.x>0.0)?r.xy : r.zw; r.x = (p.y>0.0)?r.x : r.y; vec2 q = abs(p)-b+r.x; return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r.x; } float sdPolygon( in vec2[6] v, in vec2 p ) { float d = dot(p-v[0],p-v[0]); float s = 1.0; for( int i=0, j=6-1; i<6; j=i, i++ ) { vec2 e = v[j] - v[i]; vec2 w = p - v[i]; vec2 b = w - e*clamp( dot(w,e)/dot(e,e), 0.0, 1.0 ); d = min( d, dot(b,b) ); bvec3 c = bvec3(p.y>=v[i].y,p.y<v[j].y,e.x*w.y>e.y*w.x); if( all(c) || all(not(c)) ) s*=-1.0; } return s*sqrt(d); } // The following noise credits to: @patriciogv // Available on https://thebookofshaders.com // Permutation polynomial: (34x^2 + x) mod 289 vec4 permute(vec4 x) { return mod((34.0 * x + 1.0) * x, 289.0); } // Cellular noise, returning F1 and F2 in a vec2. // Speeded up by using 2x2 search window instead of 3x3, // at the expense of some strong pattern artifacts. // F2 is often wrong and has sharp discontinuities. // If you need a smooth F2, use the slower 3x3 version. // F1 is sometimes wrong, too, but OK for most purposes. vec2 cellular2x2(vec2 P) { const float K=0.142857142857; // 1/7 const float K2=0.0714285714285; // K/2 #define jitter 0.8 // jitter 1.0 makes F1 wrong more often vec2 Pi = mod(floor(P), 289.0); vec2 Pf = fract(P); vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); vec4 ox = mod(p, 7.0)*K+K2; vec4 oy = mod(floor(p*K),7.0)*K+K2; vec4 dx = Pfx + jitter*ox; vec4 dy = Pfy + jitter*oy; vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared // Sort out the two smallest distances #if 0 // Cheat and pick only F1 d.xy = min(d.xy, d.zw); d.x = min(d.x, d.y); return d.xx; // F1 duplicated, F2 not computed #else // Do it right and find both F1 and F2 d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller d.xz = (d.x < d.z) ? d.xz : d.zx; d.xw = (d.x < d.w) ? d.xw : d.wx; d.y = min(d.y, d.z); d.y = min(d.y, d.w); return sqrt(d.xy); #endif } //The following background design credits to @del //Available at https://www.shadertoy.com/view/3dcyDj float wave(vec2 p) { float v = sin(p.x + sin(p.y) + sin(p.y * .43)); return v*v; } float get(vec2 p,float t) { mat2 rot = mat2(0.5, 0.86, -0.86, 0.5); float v = wave(p); p.y += t; p *= rot; v += wave(p.yx); p.y += t * .17; p *= rot; v += wave(p.xy); v = abs(1.5 - v); v+=pow(abs(sin(p.x+v)),18.0); return v; } void main() { const float PI=3.1415926535; vec2 fragCoord=gl_FragCoord.xy; vec2 iResolution=u_resolution; vec3 iMouse=vec3(u_mouse,0.); float iTime=0.; vec4 fragColor; //the background vec2 uv = (iResolution.xy - 2.0*fragCoord.xy)/iResolution.y; float t = iTime; float scale =14.0; float speed = .3; uv.y += sin(fract(t*0.1+uv.x)*6.28)*0.05; // wibble uv.xy += t*0.08; // scroll vec2 p = uv*scale; //p.y+= 1.0/p.y*p.y; float v = get(p,t*speed); v = smoothstep(-3.5,3.5,v); vec3 col = vec3(.29, 0.86, 0.4)*v*v; fragColor = vec4(col*v*v, 1.0); //the orchid p = (2.0*fragCoord-iResolution.xy)/iResolution.y; p *= 2.0; float theta=-PI*2./3.; float d=2.;//petal outline float s=2.;//lines on petal for (int i=0;i<5;i++){ vec2 vertex=2.*vec2(cos(theta+PI/2.),sin(theta+PI/2.)); //petal float d1=sdVesica1(p,2.01,1.8,theta); theta+=PI*1./3.; d=min(d,d1); float s1=sdSegment(p,vertex*1.2,vec2(0.,0.)); s=min(s,s1); } vec2[6] hexV=vec2[6](vec2(0.00,0.000), vec2(-0.30,0.150)*.8, vec2(-0.3,-0.25)*.8, vec2(0,-0.4)*.8, vec2(0.3,-0.25)*.8, vec2(0.3,0.15)*.8); float hex=sdPolygon(hexV,p); float tip=sdUnevenCapsule1(p,vec2(0.,0.35),vec2(0.,0.),.13,.13); float yellowCore=sdSegment(p,vec2(0.,1.3),vec2(0.,-0.1)); if (d<=0.02){//inside of the flower //petal color dark to light pink from center to the tips col=mix(vec3(220.,89.,92.),vec3(220.,170.,185.),dot(p,p)*0.4); //lines on the petal, darker in the middle vec3 veinCol=mix(vec3(198.,67.,96.),vec3(226.,155.,187.),s*4.); col=mix(col,veinCol,cos(75.*s)-.29); col/=255.; } if(tip<0.){ col=vec3(228.,193.,164.)/255.; } if(hex<0.16){//rounded outline of inside col=vec3(1.); if(hex>-0.2){//surrouding, rose red col=mix(col,vec3(188.,62.,127.)/255.,(hex+.041)*7.); //black dot noise vec2 st=p; st = (st-.5)*.75+.5; st/=.8; vec2 F = cellular2x2(st*15.); vec2 pos = st-.5; float a = dot(pos,pos)-3.8*0.1; float n = step(abs(sin(a*3.1415*5.)),F.x*2.5); if (n<0.3){ col=vec3(n+.2,n,n); } } if(yellowCore<.1){ col=mix(vec3(245.000,209.000,72.000)/255.,col-vec3(.2),yellowCore*4.); } } fragColor = vec4(col,1.0); colour_out=fragColor; }
Cymbidium cv Orchid by @amycqx
// credit: s.l uniform vec2 u_resolution; vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } float turbulence( vec3 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( snoise( p * scale ) ) / scale; } return f; } // Blends a pre-multiplied src onto a dst color (without alpha) vec3 premulMix(vec4 src, vec3 dst) { return dst.rgb * (1.0 - src.a) + src.rgb; } // Blends a pre-multiplied src onto a dst color (with alpha) vec4 premulMix(vec4 src, vec4 dst) { vec4 res; res.rgb = premulMix(src, dst.rgb); res.a = 1.0 - (1.0 - src.a) * (1.0 - dst.a); return res; } float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) { p.x = abs(p.x); float b = (r1 - r2) / h; float a = sqrt(1.0 - b * b); float k = dot(p, vec2(-b, a)); if(k < 0.0) return length(p) - r1; if(k > a * h) return length(p - vec2(0.0, h)) - r2; return dot(p, vec2(a, b)) - r1; } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r * r - d * d); return ((p.y - b) * d > p.x * b) ? length(p - vec2(0.0, b)) : length(p - vec2(-d, 0.0)) - r; } float sdDifference(float d1, float d2) { return max(-d1, d2); } float smax(float a, float b, float k) { float h = max(k - abs(a - b), 0.0); return max(a, b) + h * h * 0.25 / k; } float sdSmoothDifference(float d1, float d2, float k) { return smax(-d1, d2, k); } // The outline of a petal float petalOutline(vec2 p, float s) { vec2 centerLine = vec2(0.5, p.y); // Top if (p.y > 0.6 && p.y < 1.0) return length(p - centerLine) - 0.57 * pow(1.0 - p.y, 0.35) + s; // Middle else if (p.y < 0.6 && p.y > 0.3) return length(p - centerLine) - 0.46 * pow(0.75 - p.y, 0.06) + s; // Bottom else if (p.y < 0.3 && p.y > -0.1) return length(p - centerLine) - 0.3 / (0.832 + exp(- 16.0 * p.y + 2.0)) - 0.1 + s; // Outside else return 1.0; } // Texture of a petal float petalTexture(vec2 p) { p = (p - 0.5) * 30.0; // Strips float n = snoise(p); float strips = smoothstep(0.0, 0.3, sin(p.x * 7.2 * (pow(-0.05 * p.y, 4.0) + 0.25)) + n * 0.25); // Spots n = snoise(p * 0.4); float spots = smoothstep(0.0, 0.1, n); return clamp(strips + spots, 0.0, 1.0); } // Draw a petal with texture vec4 drawPetal(vec2 p) { // White part vec4 whitePart = vec4(1.0 - smoothstep(0.0, 0.01, petalOutline(p, 0.0))); // Pink part vec4 inside = vec4(1.0 - smoothstep(0.0, 0.01, petalOutline(p, 0.033))); inside.rgb *= vec3(0.740,0.132,0.464); // Calculate texture vec4 tex = vec4(petalTexture(p)) * inside; return premulMix(tex, whitePart);; } // Draw the pistil vec4 drawPistil(vec2 p) { vec4 color = vec4(1.0 - sign(sdUnevenCapsule(p, 0.168, 0.124, 0.312))); color.rgb *= vec3(0.983,1.000,0.848); return color; } // Draw small petals vec4 drawSmallPetals(vec2 p) { // A big versica float rad = 1.6; float c = cos(rad), s = sin(rad); float x = 0.3, y = -0.46; mat3 H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; vec2 newP = (H * vec3(p, 1.0)).xy * 5.5; float v = sdVesica(newP, 1.36, 0.2); // Part to be removed 1 rad = 2.96; c = cos(rad), s = sin(rad); x = 0.59, y = 0.13; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part1 = sdVesica(newP, 1.25, 1.0); // Part to be removed 2 rad = 0.104; c = cos(rad), s = sin(rad); x = -0.360, y = -0.272; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part2 = sdVesica(newP, 1.25, 1.0); // Part to be removed 3 rad = 1.6; c = cos(rad), s = sin(rad); x = 0.416, y = -0.456; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part3 = sdVesica(newP, 1.28, 0.62); // Get small petals by removing the three unwanted parts of the big versica float smallPetals = sdSmoothDifference(part3, sdDifference(part2, sdDifference(part1, v)), 0.2); // Calculate and return the color (The edges are white) vec4 color_inside = vec4(1.0 - smoothstep(0.0, 0.04, smallPetals)); color_inside.rgb *= vec3(0.73 ,0.13,0.46) * (p.y + 0.75); vec4 color_outside = vec4(1.0 - smoothstep(0.02, 0.04, smallPetals)); return premulMix(color_inside, color_outside); } // uniform float u_time; vec4 drawBackground(vec2 p) { // vec3 uv = vec3(p.xy, 0.04 * u_time); vec3 uv = vec3(p.xy, 0.04); float noise = 0.50 * turbulence(uv) + 0.5; return vec4( vec3(0.507,0.800,0.183), noise); } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec4 background = drawBackground(st); // Adjust the center of the orchid st += vec2(0.0, 0.05); // Draw petal 1 float rad = 0.0; float c = cos(rad), s = sin(rad); float x = -0.352, y = -0.568; mat3 H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; vec2 p = (H * vec3(st, 1.0)).xy * 3.3; vec4 petal1 = drawPetal(p); petal1.rgb *= 1.070 * pow(1.0 - p.y, 0.1); colour_out = premulMix(petal1, background); // Draw petal 2 rad = -2.416; c = cos(rad), s = sin(rad); x = 0.144, y = 0.692; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * vec2(3.5, 3.3); vec4 petal2 = drawPetal(p); petal2.rgb *= 0.9; colour_out = premulMix(petal2, colour_out); // Draw petal 3 rad = 2.360; c = cos(rad), s = sin(rad); x = 0.848, y = -0.016; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * vec2(4.0, 3.3); vec4 petal3 = drawPetal(p); petal3.rgb *= 1.1; colour_out = premulMix(petal3, colour_out); // Draw petal 4 colour_out -= vec4(vec3(0.05), 0.0); rad = 1.640; c = cos(rad), s = sin(rad); x = 0.744, y = -0.504; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 3.0; vec4 petal4 = drawPetal(p); petal4.rgb *= 0.9 * (abs(p.x - 0.5) + 1.0); colour_out = premulMix(petal4, colour_out); // Draw petal 5 rad = -1.464; c = cos(rad), s = sin(rad); x = -0.416, y = 0.408; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 3.0; vec4 petal5 = drawPetal(p); petal5.rgb *= 0.9 * (abs(p.x - 0.5) + 1.0); colour_out = premulMix(petal5, colour_out); // Draw pistil rad = 0.112; c = cos(rad), s = sin(rad); x = -0.432, y = -0.592; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 5.488; vec4 pistil = drawPistil(p); colour_out = premulMix(pistil, colour_out); // Draw small petals rad = 0.112; c = cos(rad), s = sin(rad); x = -0.200, y = -0.448; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 2.0; vec4 smallPetals = drawSmallPetals(p); colour_out = premulMix(smallPetals, colour_out); // Add some light from the top right corner colour_out += 0.1 * st.x * st.y; }
unknown by s.l
// credit: CGbaby // orchid: Phalaenopsis aphrodite uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI = 3.14159265358979324; vec2 rotate(vec2 p, float theta) { return mat2(cos(theta), -sin(theta), sin(theta), cos(theta)) * p; } float dot2(vec2 p) { return dot(p, p); } float add(float d1, float d2) { return min(d1, d2); } // d1 + d2 float diff(float d1, float d2) { return max(d1, -d2); } // d1 - d2 float random(vec2 co) { const highp float seed = 13.9898; highp float a = seed; highp float b = 78.233, c = 43758.5453; highp float dt= dot(co.xy, vec2(a,b)); highp float sn= mod(dt,PI); return fract(sin(sn) * c); } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float fbm( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += snoise( p * scale ) / scale; } return f; } float sdBezier( in vec2 pos, in vec2 A, in vec2 B, in vec2 C, in float r ) { vec2 a = B - A; vec2 b = A - 2.0*B + C; vec2 c = a * 2.0; vec2 d = A - pos; float kk = 1.0/dot(b,b); float kx = kk * dot(a,b); float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; float kz = kk * dot(d,a); float res = 0.0; float p = ky - kx*kx; float p3 = p*p*p; float q = kx*(2.0*kx*kx-3.0*ky) + kz; float h = q*q + 4.0*p3; if( h >= 0.0) { h = sqrt(h); vec2 x = (vec2(h,-h)-q)/2.0; vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); float t = clamp( uv.x+uv.y-kx, 0.0, 1.0 ); res = dot2(d + (c + b*t)*t); } else { float z = sqrt(-p); float v = acos( q/(p*z*2.0) ) / 3.0; float m = cos(v); float n = sin(v)*1.732050808; vec3 t = clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); res = min( dot2(d+(c+b*t.x)*t.x), dot2(d+(c+b*t.y)*t.y) ); // the third root cannot be the closest // res = min(res,dot2(d+(c+b*t.z)*t.z)); } return sqrt( res ) - r; } float sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } float sdPieY( in vec2 p, float t, in float r ) { vec2 c = vec2(sin(t), cos(t)); p.y = abs(p.y); float l = length(p) - r; float m = length(p-c*clamp(dot(p,c),0.0,r)); // c=sin/cos of aperture return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdParabola( in vec2 pos, in float k, bool inv ) { pos.x = abs(pos.x); float ik = 1.0/k; float p = ik*(pos.y - 0.5*ik)/3.0; float q = 0.25*ik*ik*pos.x; float h = q*q - p*p*p; float r = sqrt(abs(h)); float x = (h>0.0) ? pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q) : 2.0*cos(atan(r,q)/3.0)*sqrt(p); float sgn = inv ? -1.0 : 1.0; return sgn * length(pos-vec2(x,k*x*x)) * sign(pos.x-x); } float sdHorseshoe( in vec2 p, in float t, in float r, in vec2 w ) { vec2 c = vec2(sin(t), cos(t)); p.x = abs(p.x); float l = length(p); p = mat2(-c.x, c.y, c.y, c.x)*p; p = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), (p.x>0.0)?p.y:l ); p = vec2(p.x,abs(p.y-r))-w; return length(max(p,0.0)) + min(0.0,max(p.x,p.y)); } const int N = 4; float sdRoundedPolygon( in vec2[N] v, in vec2 p, in float r ) { float d = dot(p-v[0],p-v[0]); float s = 1.0; for( int i=0, j=N-1; i<N; j=i, i++ ) { vec2 e = v[j] - v[i]; vec2 w = p - v[i]; vec2 b = w - e*clamp( dot(w,e)/dot(e,e), 0.0, 1.0 ); d = min( d, dot(b,b) ); bvec3 c = bvec3(p.y>=v[i].y,p.y<v[j].y,e.x*w.y>e.y*w.x); if( all(c) || all(not(c)) ) s*=-1.0; } return s*sqrt(d) - r; } float petal(vec2 p) { p.x = abs(p.x - sign(p.x) * 0.005); float d1; d1 = sdPieY(p, 0.97 * PI, 0.5); d1 = diff(d1, sdCircle(p - vec2(-0.2, 0.25), 0.3)); d1 = diff(d1, sdCircle(p - vec2(-0.2, -0.25), 0.3)); float d2; d2 = sdParabola(rotate(p, 0.21 * PI) - vec2(0.364, 0.325), -15.9, true); d2 = diff(d2, sdBox(p - vec2(0, -1.15), vec2(1, 1.5))); float d3; d3 = sdParabola(rotate(p, 0.79 * PI) - vec2(-0.364, 0.325), -15.9, true); d3 = diff(d3, sdBox(p - vec2(0, 1.15), vec2(1, 1.5))); float d; d = diff(d1, d2); d = diff(d, d3); return d; } float petalLine(vec2 p) { p.x = abs(p.x - sign(p.x) * 0.005); float d1; d1 = sdBezier(p, vec2(0.2, 0), vec2(0.3, 0.0001), vec2(0.35, 0), 0.0025); float d2; d2 = sdBezier(p, vec2(0.16, 0.04), vec2(0.16, 0.0401), vec2(0.32, 0.05), 0.002); float d3; d3 = sdBezier(p, vec2(0.16, 0.07), vec2(0.25, 0.10), vec2(0.35, 0.1), 0.002); float d4; d4 = sdBezier(p, vec2(0.18, -0.04), vec2(0.25, -0.07), vec2(0.32, -0.05), 0.002); float d; d = add(d1, d2); d = add(d, d3); d = add(d, d4); return d; } float lip(vec2 p) { float d1; d1 = sdHorseshoe(p - vec2(0, -0.16), 0.1 * PI, 0.07, vec2(0.06, 0.025)); float d2; d2 = sdBox(p - vec2(0, -0.3), vec2(0.07, 0.07)); d2 = diff(d2, sdCircle(p - vec2(0.15, -0.33), 0.12)); d2 = diff(d2, sdCircle(p - vec2(-0.15, -0.33), 0.12)); float d; d = add(d1, d2); return d; } float lipLine(vec2 p) { p.x = abs(p.x); float d1; d1 = sdBezier(p, vec2(0.04, -0.20), vec2(0.055, -0.20), vec2(0.07, -0.18), 0.004); float d2; d2 = sdBezier(p, vec2(0.04, -0.22), vec2(0.055, -0.23), vec2(0.08, -0.21), 0.004); float d; d = add(d1, d2); return d; } float lipProtrusion(vec2 p) { p.x = abs(p.x); float d1; vec2[] v = vec2[]( vec2(0, 0), vec2(0.02, 0.01), vec2(0.01, -0.06), vec2(0, -0.05) ); d1 = sdRoundedPolygon(v, p - vec2(0.01, -0.18), 0.01); float d; d = d1; return d; } float dorsalSepal(vec2 p) { float d1; d1 = sdParabola(p - vec2(0, 0.7), -5.0, false); d1 = diff(d1, sdBox(p - vec2(0, -1.5), vec2(1, 1.5))); float d; //d = d1; d = diff(d1, petal(p)); return d; } float dorsalSepalLine(vec2 p) { float d1; d1 = sdBezier(p, vec2(-0.03, 0.06), vec2(-0.07, 0.18), vec2(-0.08, 0.3), 0.0025); float d2; d2 = sdBezier(p, vec2(-0.01, 0.06), vec2(-0.04, 0.15), vec2(-0.03, 0.3), 0.0025); float d3; d3 = sdBezier(p, vec2(0.01, 0.07), vec2(0.01, 0.15), vec2(0.01, 0.32), 0.0025); float d; d = add(d1, d2); d = add(d, d3); return d; } float lowerSepal(vec2 p) { float d1; d1 = sdParabola(rotate(p, 0.95 * PI) - vec2(0.21, 0.6), -6.9, false); d1 = diff(d1, sdBox(p - vec2(0, 1.48), vec2(1, 1.5))); float d2; d2 = sdParabola(rotate(p, 1.05 * PI) - vec2(-0.21, 0.6), -6.9, false); d2 = diff(d2, sdBox(p - vec2(0, 1.48), vec2(1, 1.5))); float d; d = add(d1, d2); d = diff(d, petal(p)); return d; } void main(){ vec3 color; vec2 coord = (gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0) / 1.3; float fbmVal = fbm(coord); float dLowerSepal = lowerSepal(coord); float dDorsalSepal = dorsalSepal(coord); float dDorsalSepalLine = dorsalSepalLine(coord); float dPetal = petal(coord); float dPetalLine = petalLine(coord); float dLip = lip(coord); float dLipLine = lipLine(coord); float dLipProtrusion = lipProtrusion(coord); if (dLowerSepal <= .0) { color = vec3(0.88, 0.92, 0.96); float coef = 0.08 * (1.0 - smoothstep(0.0, 0.04, dPetal)); color *= coef * fbmVal + (1.0 - coef); } if (dDorsalSepal <= .0) { color = vec3(0.88, 0.92, 0.96); float coef = 0.08 * (1.0 - smoothstep(0.0, 0.04, dPetal)); color *= coef * fbmVal + (1.0 - coef); } if (dDorsalSepalLine <= .0) { color = vec3(0.87, 0.87, 0.87); } if (dPetal <= .0) { color = vec3(0.93, 0.97, 0.98); if (abs(coord.x) >= 0.2) { color *= 1.0 - 0.03 * smoothstep(-0.10, 0.0, dPetal) * fbm(coord * 30.0); } } if (dPetalLine <= .0) { color = vec3(0.87, 0.87, 0.87); } if (dLip <= .0) { color = mix( mix(vec3(0.80, 0.67, 0), vec3(0.92, 0.96, 0.97), smoothstep(0.05, 0.08, abs(coord.x))), vec3(0.92, 0.96, 0.97), smoothstep(0.00, 0.07, abs(coord.y + 0.21)) ); } if (dLipLine <= .0) { color = vec3(0.55, 0.15, 0.14); } if (dLipProtrusion <= .0) { if (random(coord) >= 0.7) { color = vec3(0); } else { color = vec3(0.80, 0.67, 0); } } colour_out = vec4(color, 1); }
Phalaenopsis Aphrodite by CGbaby
// credit: TT // orchid: Lycaste uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI=3.1415926535897932384626433832795; float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); // can delay this sqrt by rewriting the comparison return ((p.y-b)*d > p.x*b) ? length(p-vec2(0.000,b))*sign(d) : length(p-vec2(-d,0.0))-r; } float sdCircle( in vec2 p, in float r ) { return length(p)-r; } float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { p *= mat2(sca.x,sca.y,-sca.y,sca.x); p.x = abs(p.x); float k = (scb.y*p.x>scb.x*p.y) ? dot(p.xy,scb) : length(p); return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb; } float sdPie( in vec2 p, in vec2 c, in float r ) { p.x = abs(p.x); float l = length(p) - r; float m = length(p - c*clamp(dot(p,c),0.0,r) ); return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } vec2 rotate(vec2 p, float degree){ float c = cos(degree*PI/180.); float s = sin(degree*PI/180.); mat3 H = mat3(c, s, 0, -s, c, 0, 0, 0, 1); return (inverse(H) * vec3(p,1.0)).xy; } vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } float snoise(vec2 v){ const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439); vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod(i, 289.0); vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } void main() { float mask = 1.000; vec2 p = (2.0*gl_FragCoord.xy-u_resolution.xy)/u_resolution.xy ; float ra1_a = 0.468; float ra2_a = 0.080; float wid_a = max(0.628,ra1_a); float ra1_b = 0.116; float ra2_b = -0.128; float wid_b = max(0.484,ra1_b); float ra1_c = 0.092; float ra2_c = -0.160; float wid_c = max(0.452,ra1_c); float d1 = sdVesica( rotate(p - vec2(0.380,-0.180),70.0), wid_a, ra1_a ) - ra2_a; float d2 = sdVesica( rotate(p - vec2(0.000,0.360),180.000), wid_a, ra1_a ) - ra2_a; float d3 = sdVesica( rotate(p - vec2(-0.380,-0.180),-70.0), wid_a, ra1_a ) - ra2_a; float d4 = sdVesica( rotate(p - vec2(-0.210,0.130),45.), wid_b, ra1_b ) - ra2_b; float d5 = sdVesica( rotate(p - vec2(0.210,0.130),-45.), wid_b, ra1_b ) - ra2_b; float d6 = sdVesica( rotate(p - vec2(0.000,-0.030),0.), wid_c, ra1_c ) - ra2_c; float d_c = sdCircle(p - vec2(0.000,0.070),0.052); float d_c2 = sdCircle(p - vec2(0.000,0.070),0.036); float ta = 4.732; float tb = 1.652; float rb = 0.022; float d_a = sdArc(p,vec2(sin(ta),cos(ta)),vec2(sin(tb),cos(tb)), 0.11, rb); float d_b = sdPie(rotate(p - vec2(0.000,-0.100),180.0),vec2(0.880,0.250), 0.12); float d_b2 = sdBox(rotate(p - vec2(0.270,-0.960),110.0),vec2(0.870,0.020)); vec3 colour = vec3( 1., 1., 1.); colour *= 1.0-mask; colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d1)) ); colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d2)) ); colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d3)) ); colour = mix( colour, vec3(0.317,0.735,0.040), 1.000-step(0.0, d_b2) ); colour = mix( colour, vec3(1.000,0.290,0.290), 1.000-step(0.0, d1) ); colour = mix( colour, vec3(1.000,0.290,0.290), 1.000-step(0.0, d2) ); colour = mix( colour, vec3(1.000,0.290,0.290), 1.000-step(0.0, d3) ); colour = mix( colour, vec3(1.000,0.944,0.179), 1.000-step(0.0, d6) ); colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d4)) ); colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d5)) ); colour = mix( colour, vec3(1.000), 1.000-smoothstep(0.0, 0.01, abs(d6)) ); colour = mix( colour, vec3(1.000,0.139,0.130), 1.000-step(0.0, d4) ); colour = mix( colour, vec3(1.000,0.139,0.130), 1.000-step(0.0, d5) ); colour = mix( colour, vec3(1.000,0.994,0.211), 1.000-step(0.0, d_c) ); colour = mix( colour, vec3(1.000,0.994,0.211), 1.000-smoothstep(0.0, 0.248, abs(d_c2)) ); colour = mix( colour, vec3(0.755,0.755,0.755), 1.000-smoothstep(0.0, 0.01, abs(d_c)) ); colour = mix( colour, vec3(0.705,0.026,0.074), 1.000-step(0.0, d_a) ); colour = mix( colour, vec3(0.805,0.030,0.084), 1.000-step(0.0, d_b) ); colour =(1.0-snoise(p*8.)*vec3(0.006,0.248,0.345))*colour; colour_out = vec4(colour,1.0); }
Lycaste by TT
// credit: Tsunehiko // orchid: Dendrobium kingianum uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI=3.1415926535897932384626433832795; float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) : length(p-vec2(-d,0.0))-r; } vec2 rotate(vec2 p, float degree){ float c = cos(degree * PI/180.); float s = sin(degree * PI/180.); mat3 H = mat3(c, s, 0, -s, c, 0, 0, 0, 1); return (inverse(H) * vec3(p,1.0)).xy; } float sdMoon(vec2 p, float d, float ra, float rb ) { p.y = abs(p.y); float a = (ra*ra - rb*rb + d*d)/(2.0*d); float b = sqrt(max(ra*ra-a*a,0.0)); if( d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) ) return length(p-vec2(a,b)); return max( (length(p)-ra), -(length(p-vec2(d,0))-rb)); } float sdf( vec2 p ) { if(p.y < -0.7) return 1.0; float d = sdVesica(rotate(p - vec2(0.4,0.15),135.0), 0.6, 0.5) - 0.02; d = min(d, sdVesica(rotate(p - vec2(-0.4,0.15),-135.0), 0.6, 0.5) - 0.02); d = min(d, sdVesica(rotate(p - vec2(0.0,0.3),0.0), 0.7, 0.5) - 0.02); d = min(d, sdMoon(rotate(p-vec2(0.3, -0.5), -50.0), 0.25, 0.45, 0.37)); d = min(d, sdMoon(rotate(p-vec2(-0.3, -0.5), -130.0), 0.25, 0.45, 0.37)); return d; } float sdPie( in vec2 p, in vec2 c, in float r ) { p.x = abs(p.x); float l = length(p) - r; float m = length(p-c*clamp(dot(p,c),0.0,r)); return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdf_2( vec2 p ) { float d = sdPie(rotate(p-vec2(-0.025, -0.2), 110.0), vec2(sin(75.0*PI/180.0), cos(75.0*PI/180.0)), 0.2); d = min(d, sdPie(rotate(p-vec2(0.025, -0.2), -110.0), vec2(sin(75.0*PI/180.0), cos(75.0*PI/180.0)), 0.2)); return d; } float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdf_3(vec2 p) { float d = sdCircle(p+vec2(0.02, 0.1), 0.05); d = min(d, sdCircle(p+vec2(-0.02, 0.1), 0.05)); return d; } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float fbm( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += snoise( p * scale ) / scale; } return f; } void main() { vec2 p = (gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0) / 1.1; // distance float d = sdf(p); float d_2 = sdf_2(p); float d_3 = sdf_3(p); // color vec3 lavender = mix(vec3(0.644, 0.422, 0.625), vec3(0.95, 0.95, 0.95), exp(-length(p)+0.35)-0.1); float n = fbm( gl_FragCoord.xy / 60.0 ); vec3 purple = mix(vec3(0.690,0.276,0.690), vec3(1.0), n); vec3 col = vec3(0.0); if(sign(d) < 0.0){ if(sign(d_3) < 0.0){ col = mix(vec3(0.98, 0.96, 0.87), vec3(0.8), abs(d_3)); col = mix(col, vec3(0.95), 1.0 - smoothstep(0.0,0.02,abs(d_3))); } else if(sign(d_2) < 0.0) { col = mix( purple, vec3(0.95), 1.0 - smoothstep(0.0,0.02,abs(d_2))); } else { col = lavender; } } col = mix( col, vec3(0.644, 0.422, 0.625), 1.0 - smoothstep(0.0,0.02,abs(d))); colour_out = vec4( col, 1.0 ); }
Dendrobium Kingianum by Tsunehiko
// credit: jikihakase (will show up on website) // orchid: Coelogyne pandurata uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.000,b)) : length(p-vec2(-d,-0.008))-r; } float sdPie( in vec2 p, in vec2 c, in float r ) { p.x = abs(p.x); float l = length(p) - r; float m = length(p-c*clamp(dot(p,c),0.000,r)); // c=sin/cos of aperture return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdMoon(vec2 p, float d, float ra, float rb ) { p.y = abs(p.y); float a = (ra*ra - rb*rb + d*d)/(2.0*d); float b = sqrt(max(ra*ra-a*a,0.0)); if( d*(p.x*b-p.y*a) > d*d*max(b-p.y,0.0) ) return length(p-vec2(a,b)); return max( (length(p )-ra), -(length(p-vec2(d,0))-rb)); } mat2 rotate(float degree){ float c = cos(degree), s = sin(degree); return mat2( c, -s, s, c); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy-0.5; float n = snoise(st * 30.0); vec4 color1 = vec4(0.985,0.929,0.971,1.000); vec4 color2 = vec4(0.815,0.281,0.423+n,1.000); vec4 color3 = vec4(0.645,0.083,0.404,1.000); vec4 color4 = vec4(0.879,0.915,0.701,1.000); float center =length(st-vec2(0.000,-0.020)) - 0.060; float moon1 = sdMoon(vec2(11.0,11.0) * (rotate(1.592)*st.xy)-vec2(-0.710,-0.030),0.424,1.184,0.896); float moon2 = sdVesica(vec2(3.0,7.0) * (rotate(0.000)*st.xy)-vec2(0.000,-0.570),1.272,1.168); float moon = min(moon1,moon2); float leaf1 = sdPie(vec2(2.0,1.5) * (rotate(-1.376)*st.xy)-vec2(0.040,-0.020),vec2(0.820,0.580),0.5); float leaf2 = sdPie(vec2(2.0,1.5) * (rotate(1.376)*st.xy)-vec2(-0.040,0.000),vec2(0.820,0.580),0.5); float leaf3 = sdVesica(vec2(2.6,4.2) * (rotate(0.000)*st.xy)-vec2(0.000,0.680),1.496,1.176); float leaf4 = sdVesica(vec2(3.0,4.5) * (rotate(-0.896)*st.xy)-vec2(0.070,-0.930),1.496,1.176); float leaf5 = sdVesica(vec2(3.0,4.5) * (rotate(0.896)*st.xy)-vec2(-0.070,-0.930),1.496,1.176); float leaves1 = min(leaf1,leaf2); float leaves2 = min(min(leaf3,leaf4),leaf5); if(center < 0.0){ colour_out = color4; } else{ if(moon < 0.0){ colour_out = color3; } else{ if(leaves1 < 0.0){ if(leaves1 < -0.015) colour_out = color2; else{ colour_out = color1; } } else{ if(leaves2 < 0.0){ if(leaves2 < -0.02) colour_out = color2; else colour_out = color1; } } } } }
unspecified by anonymous
More Student Works
The rest of the student works from 2021 are shown below. Note that some are very computationally expensive and may potentially cause issues with your browser. Show Other Student Works
// credit: Chen Kaishang // orchid: calanthe_discolor_lindl_sert_orchid // ref image: https://esslab.jp/~ess/images/teaching/acg/orchids/calanthe_discolor_lindl_sert_orchid_0.jpg uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI=3.1415926535897932384626433832795; /* SDFs */ float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r*r-d*d); // can delay this sqrt by rewriting the comparison return ((p.y-b)*d > p.x*b) ? length(p-vec2(0.000,b))*sign(d) : length(p-vec2(-d,0.0))-r; } float sdCircle( in vec2 p, in float r ) { return length(p)-r; } float sdArc( in vec2 p, in vec2 sca, in vec2 scb, in float ra, in float rb ) { p *= mat2(sca.x,sca.y,-sca.y,sca.x); p.x = abs(p.x); float k = (scb.y*p.x>scb.x*p.y) ? dot(p.xy,scb) : length(p); return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb; } float sdPie( in vec2 p, in vec2 c, in float r ) { p.x = abs(p.x); float l = length(p) - r; float m = length(p - c*clamp(dot(p,c),0.0,r) ); return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } vec2 rotate(vec2 p, float degree){ float c = cos(degree*PI/180.); float s = sin(degree*PI/180.); mat3 H = mat3(c, s, 0, -s, c, 0, 0, 0, 1); return (inverse(H) * vec3(p,1.0)).xy; } float intersectSDF(float distA, float distB) { return max(distA, distB); } float unionSDF(float distA, float distB) { return min(distA, distB); } float differenceSDF(float distA, float distB) { return max(distA, -distB); } /* helper func for noise */ vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } /* noise */ float snoise(vec2 v){ const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439); vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod(i, 289.0); vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float woodfbm( vec2 p ) { /* Same as the fbm before. */ float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += snoise( p * scale ) / scale; } return f; } void main() { float mask = 1.000; vec2 p = (2.0*gl_FragCoord.xy-u_resolution.xy)/u_resolution.xy ; //right leaf float ra1_a = 0.468; float ra2_a = 0.020; float wid_a = max(0.628,ra1_a); float d1 = sdVesica( rotate(p - vec2(0.480,-0.180),80.0), wid_a, ra1_a ) - ra2_a; //top leaf float ra1_b = 0.126; float ra2_b = -0.138; float wid_b = max(0.500,ra1_b); float d2 = sdVesica( rotate(p - vec2(0.,0.30),0.), wid_b, ra1_b ) - ra2_b; // top-right leaf float ra1_c = 0.468; float ra2_c = 0.020; float wid_c = max(0.628,ra1_c); float d3 = sdVesica( rotate(p - vec2(0.50,0.20),120.0), wid_c, ra1_c ) - ra2_c; // top-left leaf float ra1_d = 0.468; float ra2_d = 0.020; float wid_d = max(0.628,ra1_d); float d4 = sdVesica( rotate(p - vec2(-0.50,0.20),240.0), wid_d, ra1_d ) - ra2_d; //left leaf float ra1_e = 0.468; float ra2_e = 0.020; float wid_e = max(0.628,ra1_e); float d5 = sdVesica( rotate(p - vec2(-0.480,-0.180),-80.0), wid_e, ra1_e ) - ra2_e; // bar float d_b2 = sdBox(rotate(p - vec2(0.04,-0.200),100.0),vec2(0.20,0.10)); // union all the leaves float d = unionSDF(d1, d2); d = unionSDF(d, d3); d = unionSDF(d, d4); d = unionSDF(d, d5); vec3 f_colour = vec3(0.3,0.054,0.054); vec3 colour = f_colour; if (d<0.0){ float dist = length(p); float cof = exp(-dist * 5.0 + 1.0) ; colour = mix(f_colour, vec3(1.0), cof); } else{ colour = vec3(0.0); } if (d_b2 < 0.0){ colour = vec3(1.0); } float pattern = sin(10000.0 * -d * PI/180.0 + 10.0*u_time); colour = colour * pattern; //output colour_out = vec4(colour,1.0); }
Calanthe Discolor Lindl Sert by Chen Kaishang
// credit: yhoriuchi // orchid: Phalaenopsis orchid uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI = 3.141592653589; #define CUMSUM(T,S) { S[0]=0.0; for(int i=0;i<T.length();i++) S[i+1] =S[i]+T[i]; } #define NORMALIZE(T,S,L) { for(int i=1;i<T.length();i++) S[i] = S[i]/S[T.length()]*L; } #define GETIDX(S,ID,N) { ID=-1; for(int i=0;i<S.length();i++)ID+=int(step(S[i],N)); } #define INITIALIZE(T,S,L,ID,N) { CUMSUM(T,S); NORMALIZE(T,S,L); GETIDX(S,ID,N); } float ease_in_ease_out(float p, float n){ return (sign(p-0.5)+1.0)*0.5 + sign(0.5-p) * pow( 1.0-abs(p*2.0-1.0), n ) *0.5; } // アルファブレンド vec4 alpha_blend(vec4 back, vec4 fore){ float outA = fore.w + back.w * (1.0-fore.w); if(outA==0.0){ return vec4(0.0); }else{ return vec4( mix( back.xyz*back.w, fore.xyz, fore.w ), outA); } } // 線分 float lineseg(vec2 se, vec2 start, vec2 end, float thickness){ vec2 _se = end-start; float scale = length(_se); //長さ vec2 pos = mat2( _se.x, _se.y, _se.y, -_se.x )*(se-start)/scale/vec2(scale,1.0); pos.y = abs(pos.y); if( pos.x>0.0 && pos.x<1.0 && pos.y<thickness ) return 1.0; else return 0.0; } vec4 logo(vec2 st, vec2 lt, vec2 rb){ float W = rb.x - lt.x; float H = lt.y - rb.y; vec2 pos = vec2( (st.x-lt.x)/W, (st.y-rb.y)/H ); float v = 0.0; v += lineseg( pos, vec2( 0.00, 0.00 ), vec2( 0.26, 0.74 ), 0.015 ); // 左部分 v += lineseg( pos, vec2( 0.00, 1.00 ), vec2( 0.26, 0.26 ), 0.015 ); // 左部分 v += lineseg( pos, vec2( 0.02, 0.50 ), vec2( 0.26, 0.26 ), 0.015 ); // 左部分 v += lineseg( pos, vec2( 0.02, 0.50 ), vec2( 0.26, 0.74 ), 0.015 ); // 左部分 v += lineseg( pos, vec2( 1.00, 0.00 ), vec2( 0.74, 0.74 ), 0.015 ); // 右部分 v += lineseg( pos, vec2( 1.00, 1.00 ), vec2( 0.74, 0.26 ), 0.015 ); // 右部分 v += lineseg( pos, vec2( 0.93, 0.50 ), vec2( 0.74, 0.26 ), 0.015 ); // 右部分 v += lineseg( pos, vec2( 0.93, 0.50 ), vec2( 0.74, 0.74 ), 0.015 ); // 右部分 v += lineseg( pos, vec2( 0.26, 0.74 ), vec2( 0.74, 0.74 ), 0.015 ); // 中部分 v += lineseg( pos, vec2( 0.26, 0.26 ), vec2( 0.74, 0.26 ), 0.015 ); // 中部分 v += lineseg( pos, vec2( 0.50, 0.50 ), vec2( 1.00, 0.00 ), 0.015 ); // 中部分 v += lineseg( pos, vec2( 0.26, 0.26 ), vec2( 0.74, 0.74 ), 0.030 ); // 中部分y v += lineseg( pos, vec2( 0.26, 0.74 ), vec2( 0.50, 0.50 ), 0.030 ); // 中部分y v += lineseg( pos, vec2( 0.00, 1.00 ), vec2( 0.26, 0.74 ), 0.050 ); // en 左上 v += lineseg( pos, vec2( 0.00, 0.00 ), vec2( 0.26, 0.26 ), 0.050 ); // en 左下 v += lineseg( pos, vec2( 1.00, 1.00 ), vec2( 0.74, 0.74 ), 0.050 ); // en 右上 v += lineseg( pos, vec2( 0.02, 0.50 ), vec2( 0.18, 0.50 ), 0.040 ); // bar 左 v += lineseg( pos, vec2( 0.98, 0.50 ), vec2( 0.82, 0.50 ), 0.040 ); // bar 右 return vec4(1.0, 0.0, 1.0, 1.0) * clamp(v, 0.0, 1.0); } vec4 thankyou(vec2 st, vec2 lt, vec2 rb){ float W = rb.x - lt.x; float H = lt.y - rb.y; vec2 pos = vec2( (st.x-lt.x)/W, (st.y-rb.y)/H );/// * vec2(1.1,1.0); float v = 0.0; float b = 0.015; float B = 0.05; pos -= vec2(0.01,0.0); v += lineseg( pos, vec2( 0.02, 0.95), vec2( 0.08, 0.95), B ); // T v += lineseg( pos, vec2( 0.05, 1.0 ), vec2( 0.05, 0.0 ), b ); // T pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 0.5 ), vec2( 0.08, 0.5 ), B ); // H v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.02, 0.0 ), b ); // H v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.08, 0.0 ), b ); // H pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 0.0 ), vec2( 0.08, 1.0 ), b ); // A v += lineseg( pos, vec2( 0.05, 0.5 ), vec2( 0.08, 0.5 ), B ); // A v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.08, 0.0 ), b ); // A pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 0.0 ), vec2( 0.02, 1.0 ), b ); // N v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.08, 0.0 ), b ); // N v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.08, 0.0 ), b ); // N pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 0.0 ), vec2( 0.02, 1.0 ), b ); // K v += lineseg( pos, vec2( 0.02, 0.5 ), vec2( 0.08, 1.0 ), b ); // K v += lineseg( pos, vec2( 0.02, 0.5 ), vec2( 0.08, 0.0 ), b ); // K pos -= vec2(0.11,0.0); pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.05, 0.5 ), b ); // Y v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.05, 0.5 ), b ); // Y v += lineseg( pos, vec2( 0.05, 0.5 ), vec2( 0.05, 0.0 ), b ); // Y pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.08, 1.0 ), B ); // O v += lineseg( pos, vec2( 0.02, 0.0 ), vec2( 0.08, 0.0 ), B ); // O v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.02, 0.0 ), b ); // O v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.08, 0.0 ), b ); // O pos -= vec2(0.11,0.0); v += lineseg( pos, vec2( 0.02, 0.0 ), vec2( 0.08, 0.0 ), B ); // U v += lineseg( pos, vec2( 0.02, 1.0 ), vec2( 0.02, 0.0 ), b ); // U v += lineseg( pos, vec2( 0.08, 1.0 ), vec2( 0.08, 0.0 ), b ); // U return vec4(1.0, 1.0, 1.0, 1.0) * clamp(v, 0.0, 1.0); } //////////////////////////////////////////////////////////////////////////////// vec4 mainScene(vec2 st, float time, float duration){ st = (st-vec2(0.5,0.5))*1.1 +vec2(0.5,0.5); float ts = 1.0; float cts = 2.0; vec2 d = vec2( sin(time*ts), cos(time*ts) ); float mask0 = 1.0; float mask1 = 1.0; float mask2 = 1.0; float mask3 = 1.0; float mask4 = 1.0; mask0 *= step( abs(st.x-0.5), 0.1 )*step(st.y, 0.5); // 上 st -= d*vec2(0.02,0.03); mask1 *= step( 0.1, distance( (st.xy-vec2(0.50, 0.8))/vec2(2.0,4.0), vec2(0.0) ) ); // 上 st += d*vec2(0.07,0.03); mask2 *= step( 0.1, distance( (st.xy-vec2(0.25, 0.6))/vec2(3.0,3.0), vec2(0.0) ) ); // 左 mask2 *= step( 0.1, distance( (st.xy-vec2(0.75, 0.6))/vec2(3.0,3.0), vec2(0.0) ) ); // 右 st -= d*vec2(0.03,0.04); mask3 *= step( 0.1, distance( (st.xy-vec2(0.35, 0.3))/vec2(2.0,1.5), vec2(0.0) ) ); // 左下 mask3 *= step( 0.1, distance( (st.xy-vec2(0.65, 0.3))/vec2(2.0,1.5), vec2(0.0) ) ); // 右下 st += d*vec2(0.04,0.02); mask4 *= step( 0.1, distance( (st.xy-vec2(0.40, 0.4))/vec2(1.0,1.0), vec2(0.0) ) ); // 左 mask4 *= step( 0.1, distance( (st.xy-vec2(0.60, 0.4))/vec2(1.0,1.0), vec2(0.0) ) ); // 右 vec4 result = vec4(0.0); result = alpha_blend( result, vec4( 0.0, 0.8-st.y, 0.1*abs(sin(cts*time+0.0)), mask0 ) ); result = alpha_blend( result, vec4( st.x, st.y, abs(sin(cts*time+0.0)), (1.0-mask1)*0.9 ) ); result = alpha_blend( result, vec4( st.x, st.y, abs(sin(cts*time+0.3)), (1.0-mask2)*0.9 ) ); result = alpha_blend( result, vec4( st.x, st.y, abs(sin(cts*time+0.6)), (1.0-mask3)*0.9 ) ); result = alpha_blend( result, vec4( st.x, st.y, abs(sin(cts*time+0.9)), (1.0-mask4)*0.9 ) ); vec4[] flowerModel = vec4[]( vec4(0.0), vec4(1.0), vec4(2.0) ); return vec4(result.xyz, 1.0); } vec4 title(vec2 st, float time, float duration){ return vec4(0.8, 0.0, 0.0, 1.0); } vec4 ending(vec2 st, float time, float duration){ float[] timeschedule = float[]( 0.5, // black 1.0, // fade in 2.0, // white 1.3, // fade out 0.7); // black float start_times[ timeschedule.length()+1 ]; // 各ステップ開始時刻 int stepID; // ステップ番号 INITIALIZE( timeschedule, start_times, duration, stepID, time ); float p; switch(stepID){ case 0: p = 0.0; break; case 1: p = (time-start_times[stepID])/(start_times[stepID+1]-start_times[stepID]); break; case 2: p = 1.0; break; case 3: p = 1.0 - (time-start_times[stepID])/(start_times[stepID+1]-start_times[stepID]); break; case 4: p = 0.0; break; } float mask = ease_in_ease_out( p, 2.0 ); return alpha_blend( alpha_blend( alpha_blend( vec4(0.0,0.0,0.0,1.0), logo( st, vec2(0.8,0.2), vec2(0.9,0.1) ) ), thankyou( st, vec2(0.2,0.55), vec2(0.8,0.45) ) ), vec4(vec3(0.0),1.0-mask) ); //return vec4( logo(st, vec2(0.8,0.2), vec2(0.9,0.1) ).xyz*vec3(mask), 1.0); } // シークバー vec4 seek_bar(vec2 st, float time, float duration, float alpha){ vec4 c; if( st.y<0.015 ){ if( st.x<time/duration ){ c = vec4(1.0, 0.0, 0.0, alpha); }else{ c = vec4(0.4, 0.4, 0.4, alpha); } }else{ c = vec4(0.0); } return c; } void main() { ///// 初期設定 //// // 座標 vec2 st = gl_FragCoord.xy/u_resolution.xy; // 各シーンの時間 float[] timeschedule = float[]( 0.0, // title 30.0, // 通常 5.0 ); // ending 5.0 float start_times[ timeschedule.length()+1 ]; // 各シーンの開始時刻 ( +[シーン終了時刻] ) CUMSUM(timeschedule,start_times); float time = mod(u_time, start_times[timeschedule.length()]); // 現在時刻 float timeMax = start_times[timeschedule.length()]; // 時刻最大 int sceneID; GETIDX(start_times, sceneID, time); // シーンの特定 ///// レンダリング ///// // シーン毎にレンダリング float sceneTime = time-start_times[sceneID]; float sceneDuration = timeschedule[sceneID]; switch(sceneID){ case 0: colour_out = title( st, sceneTime, sceneDuration); break; case 1: colour_out = mainScene(st, sceneTime, sceneDuration); break; case 2: colour_out = ending( st, sceneTime, sceneDuration); break; } ///// シークバー ///// colour_out = alpha_blend( colour_out, seek_bar(st,time,timeMax, 0.8) ); }
Phalaenopsis orchid by yhoriuchi
// credit: @yuuki // orchid: Phalaenopsis Hybrid uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Shady (get it? lol) declarations that I probably ripped off of somewhere (wait a minute...) vec4 mod289(vec4 x){return x-floor(x*(1./289.))*289.;} vec3 mod289(vec3 x){return x-floor(x*(1./289.))*289.;} vec2 mod289(vec2 x){return x-floor(x*(1./289.))*289.;} vec4 permute(vec4 x){return mod289((34.*x+10.)*x);} vec3 permute(vec3 x){return mod289((34.*x+10.)*x);} vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-.85373472095314*r;} float snoise(vec3 v) { const vec2 C=vec2(1./6.,1./3.); const vec4 D=vec4(0.,.5,1.,2.); // First corner vec3 i=floor(v+dot(v,C.yyy)); vec3 x0=v-i+dot(i,C.xxx); // Other corners vec3 g=step(x0.yzx,x0.xyz); vec3 l=1.-g; vec3 i1=min(g.xyz,l.zxy); vec3 i2=max(g.xyz,l.zxy); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1=x0-i1+C.xxx; vec3 x2=x0-i2+C.yyy;// 2.0*C.x = 1/3 = C.y vec3 x3=x0-D.yyy;// -1.0+3.0*C.x = -0.5 = -D.y // Permutations i=mod289(i); vec4 p=permute(permute(permute( i.z+vec4(0.,i1.z,i2.z,1.)) +i.y+vec4(0.,i1.y,i2.y,1.)) +i.x+vec4(0.,i1.x,i2.x,1.)); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_=.142857142857;// 1.0/7.0 vec3 ns=n_*D.wyz-D.xzx; vec4 j=p-49.*floor(p*ns.z*ns.z);// mod(p,7*7) vec4 x_=floor(j*ns.z); vec4 y_=floor(j-7.*x_);// mod(j,N) vec4 x=x_*ns.x+ns.yyyy; vec4 y=y_*ns.x+ns.yyyy; vec4 h=1.-abs(x)-abs(y); vec4 b0=vec4(x.xy,y.xy); vec4 b1=vec4(x.zw,y.zw); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0=floor(b0)*2.+1.; vec4 s1=floor(b1)*2.+1.; vec4 sh=-step(h,vec4(0.)); vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy; vec4 a1=b1.xzyw+s1.xzyw*sh.zzww; vec3 p0=vec3(a0.xy,h.x); vec3 p1=vec3(a0.zw,h.y); vec3 p2=vec3(a1.xy,h.z); vec3 p3=vec3(a1.zw,h.w); //Normalise gradients vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3))); p0*=norm.x; p1*=norm.y; p2*=norm.z; p3*=norm.w; // Mix final noise value vec4 m=max(.5-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.); m=m*m; return 105.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1), dot(p2,x2),dot(p3,x3))); } float snoise(vec2 v){ const vec4 C=vec4(.211324865405187,// (3.0-sqrt(3.0))/6.0 .366025403784439,// 0.5*(sqrt(3.0)-1.0) -.577350269189626,// -1.0 + 2.0 * C.x .024390243902439);// 1.0 / 41.0 // First corner vec2 i=floor(v+dot(v,C.yy)); vec2 x0=v-i+dot(i,C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1=(x0.x>x0.y)?vec2(1.,0.):vec2(0.,1.); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12=x0.xyxy+C.xxzz; x12.xy-=i1; // Permutations i=mod289(i);// Avoid truncation effects in permutation vec3 p=permute(permute(i.y+vec3(0.,i1.y,1.)) +i.x+vec3(0.,i1.x,1.)); vec3 m=max(.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),dot(x12.zw,x12.zw)),0.); m=m*m; m=m*m; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x=2.*fract(p*C.www)-1.; vec3 h=abs(x)-.5; vec3 ox=floor(x+.5); vec3 a0=x-ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m*=1.79284291400159-.85373472095314*(a0*a0+h*h); // Compute final noise value at P vec3 g; g.x=a0.x*x0.x+h.x*x0.y; g.yz=a0.yz*x12.xz+h.yz*x12.yw; return 130.*dot(m,g); } float fbm(vec2 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=snoise(p*scale)/scale; } return f; } float fbm(vec3 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=snoise(p*scale)/scale; } return f; } float turbulence(vec3 p){ float f=0.,scale; for(int i=0;i<4;i++){ scale=pow(pow(2.,4./3.),float(i)); f+=abs(snoise(p*scale))/scale;} return f; } // End of the god-knows-what declarations // Functions for calculation float noise(vec3 v){ v.xy+=vec2(fbm(v),fbm(vec3(v.xy,v.z+1000.))); return fbm(v)*.35+.45; } // SDs ripped from https://iquilezles.org/ (thanks Inigo Quilez!) float dot2(in vec2 v){return dot(v,v);} float sdEgg(in vec2 p,in float ra,in float rb) { const float k=sqrt(3.); p.x=abs(p.x); float r=ra-rb; return((p.y<0.)?length(vec2(p.x,p.y))-r: (k*(p.x+r)<p.y)?length(vec2(p.x,p.y-k*r)): length(vec2(p.x+r,p.y))-2.*r)-rb; } float sdUnevenCapsule(vec2 p,float r1,float r2,float h) { p.x=abs(p.x); float b=(r1-r2)/h; float a=sqrt(1.-b*b); float k=dot(p,vec2(-b,a)); if(k<0.)return length(p)-r1; if(k>a*h)return length(p-vec2(0.,h))-r2; return dot(p,vec2(a,b))-r1; } float sdEquilateralTriangle(in vec2 p) { const float k=sqrt(3.); p.x=abs(p.x)-1.; p.y=p.y+1./k; if(p.x+k*p.y>0.)p=vec2(p.x-k*p.y,-k*p.x-p.y)/2.; p.x-=clamp(p.x,-2.,0.); return-length(p)*sign(p.y); } float sdPie(in vec2 p,in vec2 c,in float r) { p.x=abs(p.x); float l=length(p)-r; float m=length(p-c*clamp(dot(p,c),0.,r));// c=sin/cos of aperture return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdHeart(in vec2 p) { p.x=abs(p.x); if(p.y+p.x>1.) return sqrt(dot2(p-vec2(.25,.75)))-sqrt(2.)/4.; return sqrt(min(dot2(p-vec2(0.,1.)), dot2(p-.5*max(p.x+p.y,0.))))*sign(p.x-p.y); } float sdVesica(vec2 p,float r,float d) { p=abs(p); float b=sqrt(r*r-d*d); return((p.y-b)*d>p.x*b)?length(p-vec2(0.,b)) :length(p-vec2(-d,0.))-r; } float sdEllipse(in vec2 p,in vec2 ab) { p=abs(p);if(p.x>p.y){p=p.yx;ab=ab.yx;} float l=ab.y*ab.y-ab.x*ab.x; float m=ab.x*p.x/l;float m2=m*m; float n=ab.y*p.y/l;float n2=n*n; float c=(m2+n2-1.)/3.;float c3=c*c*c; float q=c3+m2*n2*2.; float d=c3+m2*n2; float g=m+m*n2; float co; if(d<0.) { float h=acos(q/c3)/3.; float s=cos(h); float t=sin(h)*sqrt(3.); float rx=sqrt(-c*(s+t+2.)+m2); float ry=sqrt(-c*(s-t+2.)+m2); co=(ry+sign(l)*rx+abs(g)/(rx*ry)-m)/2.; } else { float h=2.*m*n*sqrt(d); float s=sign(q+h)*pow(abs(q+h),1./3.); float u=sign(q-h)*pow(abs(q-h),1./3.); float rx=-s-u-c*4.+2.*m2; float ry=(s-u)*sqrt(3.); float rm=sqrt(rx*rx+ry*ry); co=(ry/sqrt(rm-rx)+2.*g/rm-m)/2.; } vec2 r=ab*vec2(co,sqrt(1.-co*co)); return length(r-p)*sign(p.y-r.y); } // Flower patterns adapted from http://verygoodshaderexamples.ga (← very useful website!) vec4 flower_pattern_light(){ vec3 uv=vec3(15.*gl_FragCoord.xy/u_resolution.x-.5,.1*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(1.,.1725,1.,1.),vec4(1.),noise); } vec4 flower_pattern_light_center(){ vec3 uv=vec3(15.*gl_FragCoord.xy/u_resolution.x-.5,.1*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.9725,.8706,.8706,1.),vec4(1.),noise); } vec4 flower_pattern_light_center_pink(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.8157,.5216,.9059,1.),vec4(.9686,.8078,1.,1.),noise); } vec4 flower_pattern_dark(){ vec3 uv=vec3(8.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=.8*turbulence(uv)+.2; return mix(vec4(.5255,0.,.5255,1.),vec4(.7608,.4824,.4824,1.),noise); } vec4 flower_pattern_dark_center(){ vec3 uv=vec3(8.*gl_FragCoord.xy/u_resolution.x-.5,.05*u_time); float noise=.8*turbulence(uv)+.2; return mix(vec4(.2784,.0745,.2784,1.),vec4(.4078,.2392,.2392,1.),noise); } vec4 flower_pattern_yellow(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.2*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.6353,.6588,.2784,1.),vec4(.5216,.1373,.1373,1.),noise); } vec4 flower_pattern_white(){ vec3 uv=vec3(20.*gl_FragCoord.xy/u_resolution.x-.5,.5*u_time); float noise=1.*turbulence(uv)+.2; return mix(vec4(.9843,.9451,1.,1.),vec4(1.,.9608,.7765,1.),noise); } // Background pattern (it's not very easy to give the colors a natural feel for some reason) vec4 background_pattern(){ vec3 uv=vec3(.5*gl_FragCoord.xy/u_resolution.y-.5,.01*u_time); float noise=pow(noise(uv),4.)*5.; return mix(vec4(.0941,.0353,.0745,.8),vec4(.3255,.0902,.3255,1.),noise); } void main(){ vec2 st=gl_FragCoord.xy/u_resolution.xy; float mask_flower=1.; float mask_flower_edge=0.; float mask_flower_dark=1.; float mask_flower_yellow=0.; float mask_flower_pink=1.; float mask_flower_white=1.; float c1=cos(.2);float s1=sin(.2); mat2 R1=mat2(c1,s1,-s1,c1); float c2=cos(-.2);float s2=sin(-.2); mat2 R2=mat2(c2,s2,-s2,c2); // Generate flower pedals float left_pedal=sdEgg((st.yx-vec2(.5,.3))*R1*2.,.2,.5); float left_pedal_lower=sdEgg((st.yx-vec2(.4,.3))*R1*2.5,.2,.5); float right_pedal=sdEgg((-st.yx+vec2(.5,.7))*R2*2.,.2,.5); float right_pedal_lower=sdEgg((-st.yx+vec2(.4,.7))*R2*2.5,.2,.5); float top_pedal=sdEgg((vec2(st.x,st.y*.7)-vec2(.5,.4))*9.,1.4,.5); mask_flower*=step(.3,left_pedal); mask_flower*=step(.3,left_pedal_lower); mask_flower*=step(.3,right_pedal); mask_flower*=step(.3,right_pedal_lower); mask_flower*=step(.3,top_pedal); // Generate white edges of flower pedals if(left_pedal<.3&&left_pedal>.23)mask_flower_edge+=(left_pedal-.23)*50.*distance(vec2(.5),st.xy); if(right_pedal<.3&&right_pedal>.23)mask_flower_edge+=(right_pedal-.23)*50.*distance(vec2(.5),st.xy); if(left_pedal>.3&&right_pedal>.3){ if(top_pedal<.3&&top_pedal>.23)mask_flower_edge+=(top_pedal-.23)*50.*distance(vec2(.5),st.xy); if(left_pedal_lower<.3&&left_pedal_lower>.23)mask_flower_edge+=(left_pedal_lower-.23)*30.*distance(vec2(.5),st.xy); if(right_pedal_lower<.3&&right_pedal_lower>.23)mask_flower_edge+=(right_pedal_lower-.23)*30.*distance(vec2(.5),st.xy); } // Generate under part of flower float left_rounded_triangle=sdEquilateralTriangle((st.xy/.05-vec2(8,7))*R1); float right_rounded_triangle=sdEquilateralTriangle((st.xy/.05-vec2(12,7))*R2); float lower_rounded_thing=sdPie((st.xy/.4-vec2(1.25,.4)),vec2(1.,.8),.2); float lower_lower_not_rounded_thing=sdVesica((st.xy-vec2(.5,.1))/.7,.1,.2); mask_flower_dark*=step(.4,left_rounded_triangle); mask_flower_dark*=step(.4,right_rounded_triangle); mask_flower_dark*=step(.2,lower_rounded_thing); mask_flower_dark*=step(.2,lower_lower_not_rounded_thing); // Generate center pieces of flower float center_yellow_thing=sdHeart(st.xy/.05-vec2(10,6)); float center_pink_thing=sdEllipse((st.xy-vec2(.5))/.2,vec2(.5,.1)); float center_white_thing=sdUnevenCapsule((st.xy-vec2(.5,.41))/.1,.2,.1,.5); mask_flower_yellow=step(.2,center_yellow_thing); mask_flower_white=step(.2,center_white_thing); if(center_pink_thing<.2) if(center_pink_thing<.0)mask_flower_pink=0.; else mask_flower_pink=(center_pink_thing)*5.; if(center_white_thing<.2)mask_flower_white=1.-distance(vec2(.5,.48),st.xy)*20.; // Draw the elegant flower if(mask_flower_yellow==0.)colour_out=flower_pattern_yellow(); else if(mask_flower_dark==0.)colour_out=mix(flower_pattern_dark(),flower_pattern_dark_center(),.5-distance(vec2(.5,.3),st.xy)*2.); else if(mask_flower==0.){ colour_out=mix(mix(flower_pattern_light(),vec4(1.),mask_flower_edge),flower_pattern_light_center(),distance(vec2(0.),vec2(.5,.4)-distance(vec2(.5),st.xy))/.8); colour_out=mix(flower_pattern_white(),colour_out,mask_flower_white); colour_out=mix(flower_pattern_light_center_pink(),colour_out,mask_flower_pink); } else colour_out=background_pattern(); }
Phalaenopsis Hybrid by @yuuki
// credit: wofwof (will show up on website) // orchid: pololei_flame_burrageara uniform vec2 u_resolution; vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); } float snoise(vec2 v){ const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439); vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod(i, 289.0); vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } vec4 use_red_snoise(vec2 p,float deno){ float n = snoise( p / deno ); vec4 colour_out = vec4( vec3(mix(0.0,1.0,exp(n)),0.0,0.0), 1.0 ); return colour_out; } vec4 use_yellow_snoise(vec2 p){ float n = snoise( p / 0.0296 ); vec4 colour_out = vec4( vec3(mix(0.0,1.0,exp(n)),mix(0.0,1.0,exp(n)),0.0), 1.0 ); return colour_out; } float sdEllipse( in vec2 p, in vec2 ab ) { p = abs(p); if( p.x > p.y ) {p=p.yx;ab=ab.yx;} float l = ab.y*ab.y - ab.x*ab.x; float m = ab.x*p.x/l; float m2 = m*m; float n = ab.y*p.y/l; float n2 = n*n; float c = (m2+n2-1.0)/3.0; float c3 = c*c*c; float q = c3 + m2*n2*2.0; float d = c3 + m2*n2; float g = m + m*n2; float co; if( d<0.0 ) { float h = acos(q/c3)/3.0; float s = cos(h); float t = sin(h)*sqrt(3.0); float rx = sqrt( -c*(s + t + 2.0) + m2 ); float ry = sqrt( -c*(s - t + 2.0) + m2 ); co = (ry+sign(l)*rx+abs(g)/(rx*ry)- m)/2.0; } else { float h = 2.0*m*n*sqrt( d ); float s = sign(q+h)*pow(abs(q+h), 1.0/3.0); float u = sign(q-h)*pow(abs(q-h), 1.0/3.0); float rx = -s - u - c*4.0 + 2.0*m2; float ry = (s - u)*sqrt(3.0); float rm = sqrt( rx*rx + ry*ry ); co = (ry/sqrt(rm-rx)+2.0*g/rm-m)/2.0; } vec2 r = ab * vec2(co, sqrt(1.0-co*co)); return length(r-p) * sign(p.y-r.y); } float sdStar(in vec2 p, in float r, in int n, in float m){ // next 4 lines can be precomputed for a given shape float an = 3.141593/float(n); float en = 3.141593/m; // m is between 2 and n vec2 acs = vec2(cos(an),sin(an)); vec2 ecs = vec2(cos(en),sin(en)); // ecs=vec2(0,1) for regular polygon float bn = mod(atan(p.x,p.y),2.0*an) - an; p = length(p)*vec2(cos(bn),abs(sin(bn))); p -= r*acs; p += ecs*clamp( -dot(p,ecs), 0.0, r*acs.y/ecs.y); return length(p)*sign(p.x); } float sdEgg( in vec2 p, in float ra, in float rb ) { const float k = sqrt(2.0); p.x = abs(p.x); float r = ra - rb; return ((p.y<0.0) ? length(vec2(p.x, p.y )) - r : (k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) : length(vec2(p.x+r,p.y )) - 2.0*r) - rb; } float sdf1(vec2 p,vec2 ab,float angle,vec2 move){ mat4 spin= mat4(cos(angle),sin(angle),0,0, -sin(angle),cos(angle),0,0, 0,0,1,0, 0,0,0,1); return sdEllipse((vec4(p+move,0,0)*spin).xy,ab); } float sdf2(vec2 p,float r,int n,float m){ vec2 move = vec2(-0.520,-0.430); return sdStar(p+move,r,n,m); } float sdf3(vec2 p,float ra,float rb){ vec2 move = vec2(-0.530,-0.160); return sdEgg(p+move,ra,rb); } void main() { vec2 p = gl_FragCoord.xy/u_resolution.xy; // up 3 petals if (sdf2(p,0.100,8,4.768 )<=0.0) colour_out = use_yellow_snoise(p.xy); else if (sdf1(p,vec2(0.08,0.18),1.0,vec2(-0.380,-0.490)) <= 0.0 ) colour_out = vec4(1.0,0.0,0.0,0.700); else if (sdf1(p,vec2(0.10,0.20),1.0,vec2(-0.360,-0.510)) <= 0.0 ) colour_out = use_red_snoise(p.xy,0.0296); else if (sdf1(p,vec2(0.08,0.18),-1.0,vec2(-0.690,-0.510)) <= 0.0 ) colour_out = vec4(1.0,0.0,0.0,0.700); else if (sdf1(p,vec2(0.10,0.20),-1.0,vec2(-0.690,-0.510)) <= 0.0 ) colour_out = use_red_snoise(p.xy,0.0296); else if (sdf1(p,vec2(0.08,0.18),0.0,vec2(-0.530,-0.660)) <= 0.0) colour_out = vec4(1.0,0.0,0.0,0.700); else if (sdf1(p,vec2(0.10,0.20),0.0,vec2(-0.530,-0.680)) <= 0.0) colour_out = use_red_snoise(p.xy,0.0296); else if (sdf1(p,vec2(0.08,0.18),2.0,vec2(-0.360,-0.340)) <= 0.0) colour_out = vec4(1.0,0.0,0.0,0.700); else if (sdf1(p,vec2(0.10,0.20),2.0,vec2(-0.360,-0.340)) <= 0.0) colour_out = use_red_snoise(p.xy,0.0296); else if (sdf1(p,vec2(0.08,0.18),-2.0,vec2(-0.720,-0.300)) <= 0.0) colour_out = vec4(1.0,0.0,0.0,0.700); else if (sdf1(p,vec2(0.1,0.20),-2.0,vec2(-0.720,-0.300)) <= 0.0) colour_out = use_red_snoise(p.xy,0.0296); else if (sdf3(p,0.15,0.02) <= 0.0 ) colour_out = use_red_snoise(p.xy,0.035); else colour_out = vec4(vec3(0.0),1.0); }
Pololei Flame Burrageara by wofwof
// credit: Chispark777 // orchid: Phalaenopsis Blume uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec3 permute(vec3 x) { return mod(((x*34.0)+10.0)*x,289.); } vec4 permute(vec4 x) { return mod((34.0 * x + 1.0) * x, 289.0); } vec2 cellular2x2(vec2 P) { #define K 0.142857142857 // 1/7 #define K2 0.0714285714285 // K/2 #define jitter 0.8 // jitter 1.0 makes F1 wrong more often vec2 Pi = mod(floor(P), 289.0); vec2 Pf = fract(P); vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); vec4 ox = mod(p, 7.0)*K+K2; vec4 oy = mod(floor(p*K),7.0)*K+K2; vec4 dx = Pfx + jitter*ox; vec4 dy = Pfy + jitter*oy; vec4 d = dx * dx + dy * dy; // d11, d12, d21 and d22, squared // Sort out the two smallest distances #if 0 // Cheat and pick only F1 d.xy = min(d.xy, d.zw); d.x = min(d.x, d.y); return d.xx; // F1 duplicated, F2 not computed #else // Do it right and find both F1 and F2 d.xy = (d.x < d.y) ? d.xy : d.yx; // Swap if smaller d.xz = (d.x < d.z) ? d.xz : d.zx; d.xw = (d.x < d.w) ? d.xw : d.wx; d.y = min(d.y, d.z); d.y = min(d.y, d.w); return sqrt(d.xy); #endif } float celllike(vec2 st){ st -= .5; st *= .7; vec2 F1 = cellular2x2(st*50.*(.1+1.0-dot(st,st)*5.)); float facets = 0.1+(F1.y-F1.x); float n3 = facets; n3 = step(.2,facets); return n3; } float snoise(vec2 v){ const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; i = mod(i,289.0); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float fbm( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += snoise( p * scale ) / scale; } return f; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 st1 = gl_FragCoord.xy; vec2 st2 = gl_FragCoord.xy/u_resolution.xy; st2 = (st2-.5)*1.+.5; if (u_resolution.y > u_resolution.x ) { st2.y *= u_resolution.y/u_resolution.x; st2.y -= (u_resolution.y*.5-u_resolution.x*.5)/u_resolution.x; } else { st2.x *= u_resolution.x/u_resolution.y; st2.x -= (u_resolution.x*.5-u_resolution.y*.5)/u_resolution.y; } //dots and fbm vec2 F = cellular2x2(st2*35.); vec2 pos = st-.5; float a = dot(pos,pos); float n1 = step(abs(cos(a*3.1415*4.)),F.x*2.9); float n = fbm(gl_FragCoord.xy/300.0); //cell like float n3 = celllike(st); float pct = distance(st,vec2(0.5)); float nmix1 = 0.7*n1 +0.5*n; float nmix2 = 0.5*n+0.7*n3; vec3 color = vec3(0.3,0.7,0.26); float mask = 1.0; mask *= step( 0.2, distance( st.xy, vec2(0.5,0.75) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.35,0.45) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.65,0.45) ) ); mask *= step(0.15, distance(st.xy, vec2(0.5,0.2))); if(pct <0.25){ colour_out.rgb = 1.-vec3(nmix1); } else{ colour_out.rgb = 1.-vec3(nmix2); } colour_out.rgb *= color; colour_out.a = 1.0; colour_out *= 1.-mask; colour_out = vec4(vec3(1.0) - colour_out.rgb,1.0); }
Phalaenopsis Blume by Chispark777
// credit: Zhongxi Fang // orchid: Phalaenopsis uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // Modulo 289 without a division (only multiplications) vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } // Modulo 7 without a division vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } // Permutation polynomial: (34x^2 + 6x) mod 289 vec3 permute(vec3 x) { return mod289((34.0 * x + 10.0) * x); } // Cellular noise, returning F1 and F2 in a vec2. // Standard 3x3 search window for good F1 and F2 values vec2 cellular(vec2 P) { #define K 0.142857142857 // 1/7 #define Ko 0.428571428571 // 3/7 #define jitter 1.0 // Less gives more regular pattern vec2 Pi = mod289(floor(P)); vec2 Pf = fract(P); vec3 oi = vec3(-1.0, 0.0, 1.0); vec3 of = vec3(-0.5, 0.5, 1.5); vec3 px = permute(Pi.x + oi); vec3 p = permute(px.x + Pi.y + oi); // p11, p12, p13 vec3 ox = fract(p*K) - Ko; vec3 oy = mod7(floor(p*K))*K - Ko; vec3 dx = Pf.x + 0.5 + jitter*ox; vec3 dy = Pf.y - of + jitter*oy; vec3 d1 = dx * dx + dy * dy; // d11, d12 and d13, squared p = permute(px.y + Pi.y + oi); // p21, p22, p23 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 0.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d2 = dx * dx + dy * dy; // d21, d22 and d23, squared p = permute(px.z + Pi.y + oi); // p31, p32, p33 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 1.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d3 = dx * dx + dy * dy; // d31, d32 and d33, squared // Sort out the two smallest distances (F1, F2) vec3 d1a = min(d1, d2); d2 = max(d1, d2); // Swap to keep candidates for F2 d2 = min(d2, d3); // neither F1 nor F2 are now in d3 d1 = min(d1a, d2); // F1 is now in d1 d2 = max(d1a, d2); // Swap to keep candidates for F2 d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx; // Swap if smaller d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx; // F1 is in d1.x d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz d1.y = min(d1.y, d1.z); // nor in d1.z d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done. return sqrt(d1.xy); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.3, distance( st.xy, vec2(0.5, 0.4) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.6, 0.7) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.4, 0.7) ) ); vec4 colour1 = vec4(0.890,0.856,0.801,1.000) * 1.5; vec4 colour2 = vec4(0.830,0.129,0.716,1.000) * 0.8; float noise = 1.0 / exp(cellular(st.xy*30.0).x); // float noise = 1.0 / exp(cellular(st.xy*20.0).x + cellular(st.xy*20.0).y); colour_out = colour2 * noise + colour1 * (1.0-noise); colour_out *= 1.0-mask; }
Phalaenopsis by Zhongxi Fang
// credit: maopao (will show up on website) // orchid: Blue Vanda Orchid uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 mod7(vec3 x) { return x - floor(x * (1.0 / 7.0)) * 7.0; } // Permutation polynomial: (34x^2 + 6x) mod 289 vec3 permute(vec3 x) { return mod289((34.0 * x + 10.0) * x); } vec2 cellular(vec2 P) { #define K 0.142857142857 // 1/7 #define Ko 0.428571428571 // 3/7 #define jitter 1.0 // Less gives more regular pattern vec2 Pi = mod289(floor(P)); vec2 Pf = fract(P); vec3 oi = vec3(-1.0, 0.0, 1.0); vec3 of = vec3(-0.5, 0.5, 1.5); vec3 px = permute(Pi.x + oi); vec3 p = permute(px.x + Pi.y + oi); // p11, p12, p13 vec3 ox = fract(p*K) - Ko; vec3 oy = mod7(floor(p*K))*K - Ko; vec3 dx = Pf.x + 0.5 + jitter*ox; vec3 dy = Pf.y - of + jitter*oy; vec3 d1 = dx * dx + dy * dy; // d11, d12 and d13, squared p = permute(px.y + Pi.y + oi); // p21, p22, p23 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 0.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d2 = dx * dx + dy * dy; // d21, d22 and d23, squared p = permute(px.z + Pi.y + oi); // p31, p32, p33 ox = fract(p*K) - Ko; oy = mod7(floor(p*K))*K - Ko; dx = Pf.x - 1.5 + jitter*ox; dy = Pf.y - of + jitter*oy; vec3 d3 = dx * dx + dy * dy; // d31, d32 and d33, squared // Sort out the two smallest distances (F1, F2) vec3 d1a = min(d1, d2); d2 = max(d1, d2); // Swap to keep candidates for F2 d2 = min(d2, d3); // neither F1 nor F2 are now in d3 d1 = min(d1a, d2); // F1 is now in d1 d2 = max(d1a, d2); // Swap to keep candidates for F2 d1.xy = (d1.x < d1.y) ? d1.xy : d1.yx; // Swap if smaller d1.xz = (d1.x < d1.z) ? d1.xz : d1.zx; // F1 is in d1.x d1.yz = min(d1.yz, d2.yz); // F2 is now not in d2.yz d1.y = min(d1.y, d1.z); // nor in d1.z d1.y = min(d1.y, d2.x); // F2 is in d1.y, we're done. return sqrt(d1.xy); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.3, distance( st.xy, vec2(0.5, 0.4) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.6, 0.7) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.4, 0.7) ) ); vec4 cc = vec4(0.093,0.090,0.100,0.500); float outx = cellular(st.xy*10.0).x-0.5; float sig_x = 1.0/(exp(outx/-0.15)+1.0); //sigmoid function colour_out = vec4(vec3(0.6-0.3*pow(sig_x,1.0),0.6-0.55*sig_x,1.0-0.1*sig_x),1.0-sig_x/6.0); colour_out *= 1.0-mask; }
Blue Vanda Orchid by maopao
// credit: Jyhwind // orchid: dendrobium_kingianum uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.0; mask *= step( 0.110, distance( st.xy, vec2(0.5,0.55) ) ); mask *= step( 0.190, distance( st.xy, vec2(0.5,0.4) ) + distance( st.xy, vec2(0.5,0.5) ) ); mask *= step( 0.342, distance( st.xy, vec2(0.5,0.9) ) + distance( st.xy, vec2(0.5,0.590) ) ); mask *= step( 0.230, distance( st.xy, vec2(0.240,0.710) ) + distance( st.xy, vec2(0.400,0.590) ) ); mask *= step( 0.402, distance( st.xy, vec2(0.130,0.270) ) + distance( st.xy, vec2(0.420,0.500) ) ); mask *= step( 0.230, distance( st.xy, vec2(1.0-0.240,0.710) ) + distance( st.xy, vec2(1.0-0.400,0.590) ) ); mask *= step( 0.402, distance( st.xy, vec2(1.0-0.130,0.270) ) + distance( st.xy, vec2(1.0-0.420,0.500) ) ); colour_out = vec4( 1.0, 1.136*(1.0-distance( st.xy, vec2(0.5, 0.5) )), 1.0, 1.0 ); colour_out *= 1.0-mask; if (distance(st.xy, vec2(0.5, 0.55)) < 0.112 && distance(st.xy, vec2(0.5, 0.55)) > 0.092 && st.y < 0.596) { colour_out = vec4(0.725,0.123,1.000,1.000); } }
Dendrobium Kingianum by Jyhwind
// Name: Niku-Mochi // Orchid: eastern Queen of Sheba Orhicd (Scientific name: Thelymitra speciosa) // Description: Thelymitra speciosa, commonly called the eastern Queen of Sheba, is a species of orchid in the family Orchidaceae and endemic to the south-west of Western Australia. (https://en.wikipedia.org/wiki/Thelymitra_speciosa, accessed on 2021.12.05) // Reference photos: http://orchidswa.com.au/thelymitra-sun-orchids/queen-of-sheba/ uniform vec2 u_resolution; const float pi = 3.14159; // SDF function for the intersection of two mirror-symmetric circles // Input: p (position), r (radius), d (distance btw center of circle and axis of symmetry). float sdf_vesica(vec2 p, float r, float d){ p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d > p.x*b) ? (length(p-vec2(0.0,b)) * sign(d)) : (length(p-vec2(-d,0.0)) - r); } // SDF function for drawing circles float sdf_circle(vec2 p, float r){ return length(p) - r; } // Rotation and translation of sdf_vesica() // Input: p, r, d (as sdf_vesica()), theta (rotated angle), t (translation distance) float sdf_transform(vec2 p, float r, float d, float theta, vec2 t){ float c = cos(theta), s = sin(theta); t = mat2(c, s, -s, c) * t; mat3 H = mat3(vec3(c, s, 0.0), vec3(-s, c, 0.0), vec3(vec2(t), 1.0)); p = (inverse(H) * vec3(p,1.0)).xy; return sdf_vesica(p, r, d); } // SDF function for drawing petals // Input: p, r, d (as sdf_vesica()), theta (3 rotated angles), t (3 distances) float sdf_petals(vec2 p, float r, float d, vec3 theta, vec3 t){ float d1 = sdf_transform(p, r, d, theta.x, vec2(0.0,t.x)); float d2 = sdf_transform(p, r, d, theta.y, vec2(0.0,t.y)); float d3 = sdf_transform(p, r, d, theta.z, vec2(0.0,t.z)); return min(min(d1,d2),d3); } // SDF function for drawing stamens (or pistils?) float sdf_stamens(vec2 p){ float d1 = sdf_circle(p+vec2(0.00,-0.01), 0.04); float d2 = sdf_circle(p+vec2(-0.05,-0.055), 0.03); float d3 = sdf_circle(p+vec2(0.04,-0.05), 0.027); return min(min(d1,d2),d3); } // Function for differently colored edges of petals // Input: c (petal color), edge_c (edge color), sdf_d1, sdf_d2 (petals set 1 and set 2) vec3 petal_edge(vec3 c, vec3 edge_c, float sdf_d1, float sdf_d2){ vec3 out_c = c; if (sign(sdf_d1)<=0.0){ out_c = mix(c, edge_c, smoothstep(0.03,0.00,abs(sdf_d1))); } else if (sign(sdf_d1)>0.0 && sign(sdf_d2)<=0.0){ out_c = mix(c, edge_c, smoothstep(0.10,0.00,abs(sdf_d2))); } else{ out_c = out_c; } return out_c; } // Random 2D function vec2 rand_2(vec2 p) { const highp float seed = 12.9898; highp float a = seed, b = 78.233, c = 43758.5453, d = 269.5, e = 183.3; highp float dt_1 = dot(p, vec2(a,b)); return fract(sin(vec2(dt_1,dt_1)) * c); } // Reference: Cellular Noise. https://thebookofshaders.com/12/. Accessed on 2021.12.05. float noise(vec2 p){ // Tiling vec2 int_p = floor(p), frac_p = fract(p); // Minimum distance float min_dist = 0.425; for (int j=-1; j<=1; j++){ for (int i=-1; i<=1; i++ ){ // Random offset vec2 offset = rand_2(int_p + vec2(float(i),float(j))); offset = 0.6 + 0.45 * sin(0.98*offset+100.0); // Position of the cell vec2 pos = vec2(float(i),float(j)) + offset - frac_p; min_dist = min(min_dist, min_dist*length(pos)); } } return min_dist; } void main(){ // Define color vec3 dark_magenta = vec3(0.55,0.00,0.55); vec3 green_yellow = vec3(0.78,0.85,0.68); vec3 dark_orange = vec3(0.745,0.306,0.125); vec3 yellow = vec3(0.953,0.878,0.231); vec3 black_brown = vec3(0.271,0.196,0.176); vec3 purple = vec3(0.750,0.212,0.500); // Call sdf function to create petals and stamens vec2 p = gl_FragCoord.xy / u_resolution.xy; p -= vec2(0.5); float dist = 0.27; float ra = max(0.36, dist); // Two sets of petals. Each will be applied different patterns. // Adopt different rotation angles to make the orchid more 'natrual'. float d_petals_1 = sdf_petals(p, ra, dist, vec3(1.10, 3.05, 4.88)*pi/3.0, vec3(0.22,0.19,0.21)); float d_petals_2 = sdf_petals(p, ra, dist, vec3(-0.10, 2.05, 3.95)*pi/3.0, vec3(0.20,0.20,0.20)); // Stamens float d_stamens_1 = sdf_circle(p+vec2(0.000,0.025), 0.05); float d_stamens_2 = sdf_stamens(p); // Outline of the orchid float d_petals = min(d_petals_1,d_petals_2);//union of 2 petal sets vec3 col_orc = mix(dark_magenta, green_yellow, step(0.0,d_petals)); // Pattern 1 of petals (broad reddish edges) col_orc = petal_edge(col_orc, dark_orange, d_petals_1, d_petals_2); // Pattern 2 of petals (dark spots) by calling noise func p += vec2(0.5); p *= 15.0; float d_spots = max(noise(p)-0.06, d_petals);//intersection of spots and petals col_orc = mix(black_brown, col_orc, step(0.0,d_spots)); // Draw stamens col_orc = mix(purple, col_orc, step(0.0,d_stamens_1)); col_orc = mix(yellow, col_orc, step(0.0,d_stamens_2)); // Output colour_out = vec4(col_orc,1.0); }
Thelymitra Speciosa (Eastern Queen of Sheba
Orchid) by Niku-Mochi
// credit: Big RUI(will show up on website) // orchid: phalaenopsis_hybrid_0 uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec2 random( vec2 p ) { p = vec2( dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3))); return -1.0 + 2.0*fract(sin(p)*43758.5453123); } float noise( in vec2 p ) { vec2 i = floor(p); vec2 f = fract(p); float F1 = 1.; for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { vec2 neighbor = vec2(float(j), float(k)); vec2 point = random(i + neighbor); float d = length(point + neighbor - f); F1 = min(F1,d); } } return F1; } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 pos=vec2 (st.x-0.5,st.y-0.5); float d=pos.x*pos.x+pos.y*pos.y; float mask = 1.0; float mask2 = 1.0; float mask3 = 1.0; float anti_mask = 0.0; float anti_mask2 = 0.0; float noise1 = noise( 20.944*vec2(1.808*sqrt(pos.x*pos.x)*pos.x,5.040*sqrt(pos.y*pos.y)*pos.x )); mask *= step( 0.3, distance( st.xy*vec2(0.900,0.190)*2.0, vec2(0.900,0.090) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.290,0.420) ) ); mask *= step( 0.25, distance( st.xy, vec2(0.700,0.420) ) ); mask2 *= step( 0.25, distance( st.xy*vec2(0.50,1.00)*2.0, vec2(0.320,0.170) ) ); mask2 *= step( 0.25, distance( st.xy*vec2(0.50,1.00)*2.0, vec2(0.670,0.160) ) ); mask3 *= (log2(distance( st.xy*vec2(1.00,1.00), vec2(0.500,0.270) ))*13.264+36.216) ; anti_mask += step( 1.0, distance( st.xy*vec2(0.630,0.760)*4.440, vec2(1.370,0.100) ) ); anti_mask2 += (log2(distance( st.xy*vec2(1.00,1.00), vec2(0.510,0.290) ))*0.376+1.672) ; vec4 noise_out1 = vec4(vec3(pow(noise1, 1.664)), 1.0); colour_out = vec4( mix( vec3(0.981,0.745,1.000),vec3(0.880,0.245,0.811),d*3.378),1.0); colour_out +=0.580* noise_out1; colour_out *= (1.0-mask)*(anti_mask ); vec2 pos2=vec2 (st.x-0.5,st.y-0.5); float noise2 = noise( 159.144*vec2(0.240*sqrt(pos2.x*pos2.x)*pos2.x,0.344*sqrt(pos2.y*pos2.y)*pos2.x )); vec4 noise_out2 = vec4(vec3(pow(noise2, 1.664)), 1.0); float noise3 = noise( 21.408*vec2(25.632*sqrt(pos2.x*pos2.x)*pos2.x,3.400*sqrt(pos2.y*pos2.y)*pos2.y )); colour_out += vec4( mix( vec3(0.981,0.745,1.000),vec3(0.880,0.245,0.811),0.378),4.280*d*sqrt(d))*1.252*( noise_out2 +1.0)*(1.0-mask2); colour_out *=anti_mask2*1.168; vec4 noise_out3 = vec4(vec3(pow(noise3, 1.664)), 1.0); colour_out+=0.072*(1.0-step(1.856,mask3))*(1.992-mask3)*(vec4( mix( vec3(0.970,0.815,0.639),vec3(0.880,0.411,0.100),0.634),0.968)*noise_out3*(2.872)+-0.580)+0.328; colour_out *=0.496; }
Phalaenopsis Hybrid by Big RUI
// Author name: barnacleboy // orchid: Cymbidium/boat orchid uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); } float noise (in vec2 st) { vec2 i = floor(st); vec2 f = fract(st); float a = random(i); float b = random(i + vec2(1.0, 0.0)); float c = random(i + vec2(0.0, 1.0)); float d = random(i + vec2(1.0, 1.0)); vec2 u = f*f*(3.0-2.0*f); return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; } vec4 permute(vec4 x) { return mod((34.0 * x + 1.0) * x, 289.0); } vec2 cellular2x2(vec2 P) { #define K 0.142857142857 // 1/7 #define K2 0.0714285714285 // K/2 #define jitter 0.8 // jitter 1.0 makes F1 wrong more often vec2 Pi = mod(floor(P), 289.0); vec2 Pf = fract(P); vec4 Pfx = Pf.x + vec4(-0.5, -1.5, -0.5, -1.5); vec4 Pfy = Pf.y + vec4(-0.5, -0.5, -1.5, -1.5); vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0)); p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0)); vec4 ox = mod(p, 7.0)*K+K2; vec4 oy = mod(floor(p*K),7.0)*K+K2; vec4 dx = Pfx + jitter*ox; vec4 dy = Pfy + jitter*oy; vec4 d = dx * dx + dy * dy; #if 0 d.xy = min(d.xy, d.zw); d.x = min(d.x, d.y); return d.xx; #else d.xy = (d.x < d.y) ? d.xy : d.yx; d.xz = (d.x < d.z) ? d.xz : d.zx; d.xw = (d.x < d.w) ? d.xw : d.wx; d.y = min(d.y, d.z); d.y = min(d.y, d.w); return sqrt(d.xy); #endif } float noise1(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); return mix( mix( random( i + vec2(0.0,0.0) ), random( i + vec2(1.0,0.0) ), u.x), mix( random( i + vec2(0.0,1.0) ), random( i + vec2(1.0,1.0) ), u.x), u.y); } mat2 rotate2d(float angle){ return mat2(cos(angle),-sin(angle), sin(angle),cos(angle)); } float lines(in vec2 pos, float b){ float scale = 50.880; pos *= scale; return smoothstep(0.0, .5+b*.5, abs((sin(pos.x*3.1415)+b*2.0))*.5); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; vec2 pos = vec2(0.5,0.5)-st; vec2 pos1 = vec2(st*80.0); vec2 pos2 = vec2(st*150.0); vec2 pos3 = st.yx*vec2(10.,3.); float d1 =length(vec2(0.500,0.440)-st); float d2 =length(vec2(0.500,0.520)-st); float d3 =length(vec2(0.500,0.615)-st); float d4 =length(vec2(0.500,0.570)-st); float r = length(pos)*2.080; float a = atan(pos.y,pos.x); float f = abs(cos(a*3.0)); float n1 = -noise(pos1); float n2 = -noise(pos2); float pattern = pos3.x; st.y *= u_resolution.y/u_resolution.x; pos3 = rotate2d( noise(pos3) ) * pos3; pattern = lines(pos3,.5); vec2 st1 = (st-.5)*1.+.5; if (u_resolution.y > u_resolution.x ) { st1.y *= u_resolution.y/u_resolution.x; st1.y -= (u_resolution.y*.5-u_resolution.x*.5)/u_resolution.x; } else { st1.x *= u_resolution.x/u_resolution.y; st1.x -= (u_resolution.x*.5-u_resolution.y*.5)/u_resolution.y; } st1 -= .5; st1 *= .7; vec2 F = cellular2x2(st1*40.*(.1+1.0-dot(st1,st1)*5.)); float facets = 0.1+(F.y-F.x); float dots = smoothstep(-1.0, 0.1, F.x); float n4 = facets * dots; n4 = step(.2,facets)*dots; if(st.x>0.495&&st.x<0.505&&st.y>0.42&&st.y<0.52) colour_out = vec4(1.000,0.818,0.243,1.0); else if (d1>0.07&&d1<0.1&&d2>0.1||d2>0.07&&d2<0.1&&d3>0.075&&d1>0.05) colour_out = vec4(-vec3(n1)+vec3(0.291,0.149,0.425), 1.0); else if(d2<0.1&&d3>0.075||d1<0.1) colour_out=vec4(mix(vec4(1.0),vec4(0.995,0.826,0.050,1.000),exp((-25.600)*d2))); else if(d4<0.05) colour_out = vec4((vec3(pattern))+vec3(0.995,0.607,0.093), 1.0); else colour_out = vec4(vec3(1.0)-vec3(n4)+vec3(0.870,0.487,0.623),1.0-smoothstep(f,f+0.1,r) ); }
Cybidium/boat orchid by barnacleboy
// credit: Liu Yang (will show up on website) // orchid: phalaenopsis_hybrid_0 uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; #define PI 3.14159265358979323846 float smoothMerge(float d1, float d2, float k){ float h = clamp(0.5 + 0.5*(d2 - d1)/k, 0.0, 1.0); return mix(d2, d1, h) - k * h * (1.0-h); } float substract(float d1, float d2){ return max(-d1, d2); } float intersect(float d1, float d2){ return max(d1, d2); } float ellipseDist(vec2 p, float radius, vec2 dim){ vec2 pos = p; pos.x = p.x / dim.x; pos.y = p.y / dim.y; return length(pos) - radius; } float circleDist(vec2 p, float radius){ return length(p) - radius; } mat2 rotate2dm(float _angle){ return mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle)); } float when_eq(float x, float y) { return 1.0 - abs(sign(x - y)); } vec2 tile (vec2 _st, float _zoom) { _st *= _zoom; return fract(_st); } float orcSepals(vec2 toCenter, float resize, float defX, float defY, float grow, float nPetals, float smoothness){ float angle = atan(toCenter.y,toCenter.x) + 0.5; float deformOnY = toCenter.y * defY; float deformOnX = abs(toCenter.x) * defX; float radius = length(toCenter)*resize * (grow+deformOnY+deformOnX); float f = cos(angle*nPetals); return smoothstep(f, f+smoothness,radius); } float lip(vec2 pos, vec2 oval, vec2 ovalSub,float radius, float offset){ float A = ellipseDist(pos, radius, oval); vec2 posB = pos; posB.y += offset; float B = ellipseDist(posB, radius, ovalSub); float p = smoothMerge(B, A, 0.5); return p; } float orcColumn(vec2 pos, vec2 oval, vec2 ovalSub,float radius, float offset){ float A = ellipseDist(pos, radius, ovalSub); vec2 posB = pos; posB.y -= offset; float B = ellipseDist(posB, radius, oval); float p = substract(B,A); posB.y += 0.035; float cone = ellipseDist(posB, radius, vec2(0.055, 0.30)); p = smoothMerge(cone,p, 0.4); float s = ellipseDist(posB, radius, vec2(0.2, 0.20)); return p; } float flip(float v, float pct){ return mix(v, 1. - v, pct); } float fillSmooth(float sdfVal, float size, float smoothness){ return smoothstep(size, size+smoothness,sdfVal); } float strokeSmoot(float x, float pos, float width, float smtness){ return smoothstep(pos, pos+smtness,x+ width*0.5) - smoothstep(pos, pos+smtness,x- width*0.5); } float rand(vec2 uv){ return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); } void main(){ float smoothness = 0.03; vec2 st = gl_FragCoord.xy/u_resolution.xy; st.x *= u_resolution.x / u_resolution.y; vec2 orcSt = tile(st,1.0); // Orchid parameters. The orchid is composed by sepals, petals, lip and column orcSt+=vec2(-0.5, -0.5); //column parameters float colResize = 0.45; vec2 posCol = orcSt; posCol.y += 0.035; float colYoffset = -0.051; float powerCol = 2.; vec2 colRatio = vec2(0.7*colResize, 0.7*colResize); vec2 colSubRatio = vec2(0.9*colResize, 0.9*colResize); float colRadius = 0.52*colResize; // sepals parameters float addSmoothnessToSetals = 2.9; float deformX = 0.; float deformY = 0.; float resizePetals = 11.9; float powerSepals = 2.0; float nPetals = 3.; float growSepals = exp2(length(orcSt)) * 0.19; float nPetalsLat = 2.; float deformXLat = 0.0; float deformYLat = -0.0; float resizePetalsLat = 21.9; float powerLat = 2.3; vec2 latPos = orcSt*rotate2dm(PI*2.0/2.4); float growLaterals = pow(length(orcSt), powerLat); // lip parameter vec2 posLip = orcSt; posLip.y += 0.18; float lipResize = 0.6; float lipYoffset = 0.05; vec2 lipRatio = vec2(0.19*lipResize, 0.45*lipResize); vec2 smallLipRatio = vec2(0.3*lipResize, 0.15*lipResize); float lipRadius = 1.*lipResize; float column = orcColumn(posCol*rotate2dm(PI), colRatio, colSubRatio, colRadius, colYoffset); float sepals = orcSepals(orcSt, resizePetals, deformX, deformY, growSepals, nPetals, smoothness+addSmoothnessToSetals); float latPetals = orcSepals(latPos, resizePetalsLat, deformXLat, deformYLat, growLaterals, nPetalsLat, smoothness+addSmoothnessToSetals); float lip = lip(posLip, lipRatio, smallLipRatio, lipRadius, lipYoffset); float orchids = min(latPetals, sepals); orchids = min(orchids, lip); orchids = substract(column, orchids); float angle = atan(orcSt.y,orcSt.x) + 0.5; // this angle is using while creating the colors vec3 lip_Color = vec3(0.843,0.125,0.101);//花中间和花屁股 vec3 sepals_Texture_Color = vec3(0.898,0.229,0.394); //纹路 vec3 sepals_Color = vec3(0.387,0.033,0.500);//1 vec3 petals_Color = vec3(0.772,0.324,0.946);//花朵 vec3 points_Color = vec3(0.832,0.081,0.843); vec3 line_Color = vec3(0.603,0.077,0.545); // Background vec3 bgCol = vec3(0,0,0); // Sepals color: sepals = fillSmooth(sepals,0.09,smoothness+0.005); vec3 sepalsColor = mix(sepals_Texture_Color, sepals_Color, rand(orcSt)); vec3 orcColor = mix(sepalsColor, bgCol, sepals); // Lip color: // 1 create the space coord for the points vec2 lipSt = orcSt; lipSt = fract(lipSt *= 20.); lipSt -=vec2(0.5,0.5); // 2 create the color points float points = circleDist(lipSt, 0.1); points = smoothstep(points, points+0.05, 0.2); vec3 colorPoints = mix(lip_Color, points_Color, points); // 3 mix the color with the orchid lip = fillSmooth(lip,0.09,smoothness+0.005); orcColor = mix(colorPoints, orcColor, lip); // Petals color latPetals = fillSmooth(latPetals,0.09,smoothness+0.005); vec3 latPetalsColor = mix(line_Color, petals_Color, sin(angle * 40.0)); latPetalsColor = mix(latPetalsColor, petals_Color, abs(orcSt.x)*2.7); orcColor = mix(latPetalsColor,orcColor,latPetals); //column color column = fillSmooth(column,0.01,0.02); vec3 columnColor = lip_Color - petals_Color * (orcSt.y *2.); orcColor = mix(columnColor, orcColor, column); colour_out = vec4(vec3(orcColor),1.0); }
Phalaenopsis Hybrid by Liu Yang
uniform vec2 u_resolution; uniform float u_time; #define TWO_PI 6.28318530718 #define PI 3.1415926535 // credit: oneAAAIaDayKeepsHairAway // orchid: Phalaenopsis Orchid Stem Green // cloud source code is from ShaderToy vec2 mod289(vec2 x) { return x - floor(x * (1. / 289.)) * 289.; } vec4 mod289(vec4 x) { return x - floor(x * (1. / 289.)) * 289.; } vec4 mod7(vec4 x) { return x - floor(x * (1. / 7.)) * 7.; } vec4 permute(vec4 x) { return mod289((34. * x + 10.) * x); } vec2 cellular2x2(vec2 P) { #define K.142857142857// 1/7 #define K2.0714285714285// K/2 #define jitter.8// jitter 1.0 makes F1 wrong more often vec2 Pi = mod289(floor(P)); vec2 Pf = fract(P); vec4 Pfx = Pf.x + vec4(-.5, -1.5, -.5, -1.5); vec4 Pfy = Pf.y + vec4(-.5, -.5, -1.5, -1.5); vec4 p = permute(Pi.x + vec4(0., 1., 0., 1.)); p = permute(p + Pi.y + vec4(0., 0., 1., 1.)); vec4 ox = mod7(p) * K + K2; vec4 oy = mod7(floor(p * K)) * K + K2; vec4 dx = Pfx + jitter * ox; vec4 dy = Pfy + jitter * oy; vec4 d = dx * dx + dy * dy;// d11, d12, d21 and d22, squared // Sort out the two smallest distances #if 0 // Cheat and pick only F1 d.xy = min(d.xy, d.zw); d.x = min(d.x, d.y); return vec2(sqrt(d.x));// F1 duplicated, F2 not computed #else // Do it right and find both F1 and F2 d.xy = (d.x < d.y) ? d.xy : d.yx;// Swap if smaller d.xz = (d.x < d.z) ? d.xz : d.zx; d.xw = (d.x < d.w) ? d.xw : d.wx; d.y = min(d.y, d.z); d.y = min(d.y, d.w); return sqrt(d.xy); #endif } float color(vec2 xy) { return cellular2x2(xy).x * 2. - 1.; } vec4 mainImage(vec2 fragcoord, vec2 uresolution) { vec2 p = (fragcoord.xy / uresolution.y) * 2. - 1.; vec3 xyz = vec3(p, 0); float n = color(xyz.xy * 3.); vec4 fragColor = vec4(2. + .2 * vec3(n, n, n), 1.); return fragColor; } //orchid mat2 rotate2d(float _angle) { return mat2(cos(_angle), -sin(_angle), sin(_angle), cos(_angle)); } float orchidSides(vec2 toCenter, float resize, float defX, float defY, float grow, float nPetals, float smoothness, float xfactor) { float angle = atan(toCenter.y, toCenter.x / xfactor); float deformOnY = abs(toCenter.y) * defY; float deformOnX = abs(toCenter.x) * defX; float radius = length(toCenter) * resize * (grow + deformOnY + deformOnX) / 1.3; float f = cos(angle * nPetals); return smoothstep(f, f + smoothness, radius); } const float timeScale = 10.; const float cloudScale = .2; const float softness = .2; const float brightness = 1.; const int noiseOctaves = 8; const float curlStrain = 3.; float saturate(float num) { return clamp(num, 0., 1.); } float noise(vec2 uv) { return color(uv); } float sdSegment(vec2 p, vec2 a, vec2 b) { vec2 ap = p - a; vec2 ab = b - a; float h = clamp(dot(ap, ab) / dot(ab, ab), 0., 1.); return length(ap - ab * h); } float random(vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); } vec2 rotate(vec2 uv) { uv = uv + noise(uv * .2) * .005; float rot = curlStrain; float sinRot = sin(rot); float cosRot = cos(rot); mat2 rotMat = mat2(cosRot, -sinRot, sinRot, cosRot); return uv * rotMat; } float fbm(vec2 uv) { float rot = 1.57; float f = 0.; float total = 0.; float mul = .5; for(int i = 0; i < noiseOctaves; i++) { f += noise(uv + u_time * .00015 * timeScale * (1. - mul)) * mul; total += mul; uv *= 3.; uv = rotate(uv); mul *= .5; } return f / total; } float easeOutCubic(float number) { return 1. - pow(1. - number, 3.); } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec2 uv = gl_FragCoord.xy / (4000. * cloudScale); vec2 stTrans = (st * 2. - 1.); float angle = atan(stTrans.y / stTrans.x); vec2 a = vec2(0., 0.); vec2 b = vec2(.35, .35) * random(stTrans); vec2 rotateSt1 = vec2(rotate2d(angle * 100. * random(stTrans))); float cover = 1.1 + .1; float bright = brightness * (1.8 - cover); float color1 = fbm(uv - .5 + u_time * .004 * timeScale); float color2 = fbm(uv - 10.5 + u_time * .002 * timeScale); float clouds1 = smoothstep(1. - cover, min((1. - cover) + softness * 2., 1.), color1); float clouds2 = smoothstep(1. - cover, min((1. - cover) + softness, 1.), color2); float cloudsFormComb = saturate(clouds1 + clouds2); vec4 skyCol = vec4(.6, .8, 1., 1.); float cloudCol = saturate(saturate(1. - pow(color1, 1.) * .2) * bright); vec4 clouds1Color = vec4(cloudCol, cloudCol, cloudCol, 1.); vec4 clouds2Color = mix(clouds1Color, skyCol, .25); vec4 cloudColComb = 1.5 * mix(clouds1Color, clouds2Color, saturate(clouds2 - clouds1)); vec4 cloud_colour = mix(skyCol, cloudColComb, cloudsFormComb); //orchid float mask = 1.; mask *= orchidSides(st - .5, 1., 0., 0., 3., 2., .1, .5); mask *= orchidSides(rotate2d(PI / 2.) * (st - .5), 1., 0., 3., 3., 1., .05, 1.); mask *= orchidSides(rotate2d(PI * 6. / 4.) * (st - .5), 1.2, 1., 3., 3., 1., .05, 1.); float fun = 1. * exp(-1. * sqrt(pow(st.x - .5, 2.) + pow(st.y - .5, 2.))); vec4 objcolor = mix(vec4(1.), vec4(.478, .568, .176, 1.), fun); colour_out = mainImage(gl_FragCoord.xy, u_resolution.xy) * objcolor; if(1. - mask == 1.) { colour_out *= (1. - mask); if(distance(0., rotateSt1.x) <= .03) { colour_out *= vec4(0.4431, 1., 0.1941, 1.0); } float t = 0.; for(int i = 0; i <= 55; i++) { t += 1.; b.y += pow(-1., t) * .1 * abs(cos(t)); b *= rotate2d(PI / 27.); if(sdSegment(stTrans.xy, a, b) <= .01) { if(i > 12 && i < 28) colour_out = vec4(.478, .768, .176, .9) * (2. - distance(stTrans, vec2(0.))); else if(i > 38 && i < 55) colour_out = vec4(.478, .768, .176, .9) * (2. - distance(stTrans, vec2(0.))); // else // colour_out = vec4(0.4431, 1., 0.1941, 1.0) * (2. - distance(stTrans, vec2(0.0))); } } if(distance(vec2(0.), stTrans) < .05 * cos(stTrans.y * 15. * PI)) { colour_out = vec4(.9608, .8902, .2627, 1.); } } else colour_out = cloud_colour; // colour_out = objcolor*orchids; }
Phalaenopsis Orchid Stem Green by
oneAAAIaDayKeepsHairAway
// credit: Doclaf.eth // orchid: Dracula simia uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; vec2 random3(vec2 st){ st = vec2( dot(st,vec2(127.1,311.7)), dot(st,vec2(269.5,183.3)) ); return -1.392 + 1.968*fract(sin(st)*43755.897); } vec2 random2(vec2 st){ st = vec2( dot(st,vec2(0.100,0.200)), dot(st,vec2(0.000,0.210)) ); return -1.464 + -0.160*fract(sin(st)*43763.681); } // Gradient Noise by Inigo Quilez - iq/2013 // https://www.shadertoy.com/view/XdXGW8 float noise(vec2 st) { vec2 i = floor(st); vec2 f = fract(st); vec2 u = f*f*(3.0-2.0*f); return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x), mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y); } void main() { vec2 st = gl_FragCoord.xy/u_resolution.xy; float mask = 1.; mask *= step( 0.25, distance( st.xy, vec2(0.30,0.320) ) );//bottom left leaf mask *= step( 0.25, distance( st.xy, vec2(0.70,0.320) ) );//bottom right leaf mask *= step( 0.25, distance( st.xy, vec2(0.50,0.680) ) );//top leaf vec3 color = vec3(0.0); float t = 0.712; // Uncomment to animate //t = abs(1.0-sin(u_time*.1))*5.; // Comment and uncomment the following lines: // gradual color from center color = vec3(mix(0.280, 1.0, exp(-length(random3(st).xy)*-0.480)), 1.0, 0.560); st += noise(st*2.)*t; // Animate the coordinate space color -= vec3(1.) * smoothstep(0.844,-0.200,noise(st)); // lighting effects color += smoothstep(0.182,0.208,noise(st*1.520)); // inner structure color += smoothstep(0.206,0.344,noise(st*10.088)); // outer structure colour_out = vec4(color, 1.); //colour_out = vec4( 1, .05, .05, 0.5 ); colour_out *= 1.-mask; }
Dracula Simia by Doclaf.eth
// credit: takuto // orchid: Phalaenopsis #define PI 3.14159265358979323846 #define TAU (2.0*PI) uniform vec2 u_resolution; uniform float u_time; vec3 olive = vec3(0.482, 0.5, 0.29); vec3 red = vec3(0.952, 0.227, 0.152); vec3 orange = vec3(1.0, 1.0, 0.2); vec3 yellow = vec3(0.956, 0.898, 0.247); vec3 black = vec3(0.0); vec3 white = vec3(1.0); vec3 gray = vec3(0.147); vec3 pink = vec3(1.0, 0.69, 0.66); vec3 green = vec3(0.20, 0.52, 0.13); float merge(float d1, float d2){ return min(d1, d2); } float smoothMerge(float d1, float d2, float k){ float h = clamp(0.5 + 0.5*(d2 - d1)/k, 0.0, 1.0); return mix(d2, d1, h) - k * h * (1.0-h); } float substract(float d1, float d2){ return max(-d1, d2); } float ellipseDist(vec2 p, float radius, vec2 dim){ vec2 pos = p; pos.x = p.x / dim.x; pos.y = p.y / dim.y; return length(pos) - radius; } float circleDist(vec2 p, float radius){ return length(p) - radius; } mat2 rotate2dm(float _angle){ return mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle)); } vec2 rotate2D (vec2 _st, float _angle) { _st = rotate2dm(_angle) * _st; return _st; } float when_eq(float x, float y) { return 1.0 - abs(sign(x - y)); } float orcSepals(vec2 toCenter, float resize, float defX, float defY, float grow, float nPetals, float smoothness){ float angle = atan(toCenter.y,toCenter.x) + 0.5; float deformOnY = toCenter.y * defY; float deformOnX = abs(toCenter.x) * defX; float radius = length(toCenter)*resize * (grow+deformOnY+deformOnX); float f = cos(angle*nPetals); return smoothstep(f, f+smoothness,radius); } float lip(vec2 pos, vec2 oval, vec2 ovalSub,float radius, float offset){ float A = ellipseDist(pos, radius, oval); vec2 posB = pos; posB.y += offset; float B = ellipseDist(posB, radius, ovalSub); float p = smoothMerge(B, A, 0.5); return p; } float orcColumn(vec2 pos, vec2 oval, vec2 ovalSub,float radius, float offset){ float A = ellipseDist(pos, radius, ovalSub); vec2 posB = pos; posB.y -= offset; float B = ellipseDist(posB, radius, oval); float p = substract(B,A); posB.y += 0.035; float cone = ellipseDist(posB, radius, vec2(0.055, 0.30)); p = smoothMerge(cone,p, 0.4); float s = ellipseDist(posB, radius, vec2(0.2, 0.20)); return p; } float fillSmooth(float sdfVal, float size, float smoothness){ return smoothstep(size, size+smoothness,sdfVal); } float rand(vec2 uv){ return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453); } float cW = 2.0; float cH = 1.5; float bool2sign(int x) { /* if (x == 0) return 1.0; */ /* else return -1.0; */ /* return 1.0; */ return float(-1 * x + (1 - x)); } float modfloat(float x, float a) { return x - floor(x / a) * a; } vec4 drawOrchid(vec3 bg_color) { float smoothness = 0.05; vec2 st = gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0; st.x *= u_resolution.x / u_resolution.y; float x = st.x + 0.5 * u_time; float y = st.y + 0.3 * u_time; x = bool2sign(int((x + cW / 2.0) / cW) % 2) * (modfloat(x + cW / 2.0, cW) - cW / 2.0); y = bool2sign(int((y + cH / 2.0) / cH) % 2) * (modfloat(y + cH / 2.0, cH) - cH / 2.0); st.xy = vec2(x, y); st = rotate2D(st,TAU*u_time*0.15); // Orchid parameters. The orchid is composed by sepals, petals, lip and column //column parameters float colResize = 0.45; vec2 posCol = st; posCol.y += 0.035; float colYoffset = -0.051; float powerCol = 2.0; vec2 colRatio = vec2(0.7*colResize, 0.7*colResize); vec2 colSubRatio = vec2(0.9*colResize, 0.9*colResize); float colRadius = 0.52*colResize; // sepals parameters float addSmoothnessToSetals = 2.9; float deformX = 0.0; float deformY = 0.0; float resizePetals = 11.9; float powerSepals = 2.0; float nPetals = 3.0; float growSepals = exp2(length(st)) * 0.19; float nPetalsLat = 2.0; float deformXLat = 0.0; float deformYLat = -0.0; float resizePetalsLat = 21.9; float powerLat = 2.3; vec2 latPos = st*rotate2dm(TAU/2.4); float growLaterals = pow(length(st), powerLat); // lip parameter vec2 posLip = st; posLip.y += 0.18; float lipResize = 0.6; float lipYoffset = 0.05; vec2 lipRatio = vec2(0.19*lipResize, 0.45*lipResize); vec2 smallLipRatio = vec2(0.3*lipResize, 0.15*lipResize); float lipRadius = 1.0*lipResize; float column = orcColumn(posCol*rotate2dm(TAU/2.0), colRatio, colSubRatio, colRadius, colYoffset); float sepals = orcSepals(st, resizePetals, deformX, deformY, growSepals, nPetals, smoothness+addSmoothnessToSetals); float latPetals = orcSepals(latPos, resizePetalsLat, deformXLat, deformYLat, growLaterals, nPetalsLat, smoothness+addSmoothnessToSetals); float lip = lip(posLip, lipRatio, smallLipRatio, lipRadius, lipYoffset); float orchids = merge(latPetals, sepals); orchids = merge(orchids, lip); orchids = substract(column, orchids); // this angle is using while creating the colors float angle = atan(st.y,st.x) + 0.5; // Sepals color: sepals = fillSmooth(sepals,0.09,smoothness+0.005); vec3 sepalsColor = mix(yellow, white, rand(st)); vec3 orcColor = mix(sepalsColor, bg_color, sepals); // Lip color: // 1) create the space coord for the dots vec2 lipSt = st; lipSt = fract(lipSt *= 20.0); lipSt -= vec2(0.5,0.5); // 2 create the color dots float dots = circleDist(lipSt, 0.1); dots = smoothstep(dots, dots+0.05, 0.2); vec3 colorPoints = mix(green, white, dots); // 3 mix the color with the orchid lip = fillSmooth(lip,0.09,smoothness+0.005); orcColor = mix(colorPoints, orcColor, lip); // Petals color latPetals = fillSmooth(latPetals,0.09,smoothness+0.005); vec3 latPetalsColor = mix(yellow, red, sin(angle * 40.0)); latPetalsColor = mix(latPetalsColor, red, abs(st.x)*2.7); orcColor = mix(latPetalsColor,orcColor,latPetals); // column color column = fillSmooth(column,0.01,0.02); vec3 columnColor = orange - red * (st.y *2.0); orcColor = mix(columnColor, orcColor, column); return vec4(vec3(orcColor),1.0); } #define fs(i) (fract(sin((i)*114.514)*1919.810)) #define lofi(i,j) (floor((i)/(j))*(j)) float seed; mat2 r2d(float t) { return mat2(cos(t),sin(t),-sin(t),cos(t)); } mat3 orthBas(vec3 z) { z = normalize(z); vec3 up = abs(z.y)>0.999?vec3(0,0,1):vec3(0,1,0); vec3 x = normalize(cross(up,z)); return mat3(x,cross(z,x),z); } float random() { seed++; return fs(seed); } vec3 uniformLambert(vec3 n) { float p = TAU*random(); float cost = sqrt(random()); float sint = sqrt(1.0-cost*cost); return orthBas(n)*vec3(cos(p)*sint,sin(p)*sint,cost); } vec4 tbox(vec3 ro,vec3 rd,vec3 s) { vec3 or = ro/rd; vec3 pl = abs(s/rd); vec3 f = -or-pl; vec3 b = -or+pl; float fl = max(f.x,max(f.y,f.z)); float bl = min(b.x,min(b.y,b.z)); if (bl<fl||fl<0.0) return vec4(1E2); vec3 n = -sign(rd)*step(f.yzx,f.xyz)*step(f.zxy,f.xyz); return vec4(n,fl); } struct QTR { vec3 cell; vec3 pos; float len; float size; bool hole; }; bool isHole(vec3 p) { if (abs(p.x)<0.5&&abs(p.y)<0.5) return true; float dice = fs(dot(p,vec3(-2.0,-5.0,7.0))); if (dice<0.3) return true; return false; } QTR qt(vec3 ro,vec3 rd){ vec3 haha = lofi(ro+rd*1E-2,0.5); float ha = fs(dot(haha,vec3(6.0,2.0,0.0))); ha = smoothstep(-0.2,0.2,sin(0.5*u_time+TAU*(ha-0.5))); ro.z += ha; QTR r; r.size = 1.0; for (int i= 0; i<4; i++) { r.size /= 2.0; r.cell = lofi(ro+rd*1E-2*r.size,r.size)+r.size/2.0; if(isHole(r.cell)) break; float dice = fs(dot(r.cell,vec3(5.0,6.0,7.0))); if(dice>r.size) break; } vec3 or = (ro-r.cell)/rd; vec3 pl = abs(r.size/2./rd); vec3 b = -or+pl; r.len = min(b.x,min(b.y,b.z)); r.pos = r.cell-vec3(0.0,0.0,ha); r.hole = isHole(r.cell); return r; } vec4 drawBackground() { vec2 uv = gl_FragCoord.xy/u_resolution.xy; vec2 p = uv*2.0-1.0; p.x *= u_resolution.x/u_resolution.y; /* seed = texture(iChannel0,p).x; */ seed = fract(u_time); float haha = u_time*62.0/60.0; float haha2 = floor(haha)-.2*exp(-fract(haha)); p = r2d(u_time*0.2+0.2*floor(haha))*p; vec3 ro0 = vec3(0.0,0.0,1.0); ro0.z -= haha2; ro0 += 0.02*vec3(sin(u_time*1.36),sin(u_time*1.78),0.0); vec3 rd0 = normalize(vec3(p,-1.0)); vec3 ro = ro0; vec3 rd = rd0; vec3 fp = ro+rd*2.0; ro += vec3(0.04*vec2(random(),random())*mat2(1.0,1.0,-1.0,1.0),0.0); rd = normalize(fp-ro); float rl = 0.01; vec3 rp = ro+rd*rl; vec3 col = vec3(0.0); vec3 colRem = vec3(1.0); float samples = 1.0; for (int i= 0; i<200; i++) { QTR qtr = qt(rp,rd); vec4 isect; if (qtr.hole) { isect = vec4(1E2); } else { float size = qtr.size*0.5; size -= 0.01; size -= 0.02*(0.5+0.5*sin(5.0*u_time+15.0*qtr.cell.z)); isect = tbox(rp-qtr.pos,rd,vec3(size)); } if (isect.w<1E2) { float fog = exp(-.2*rl); colRem *= fog; rl += isect.w; rp = ro+rd*rl; vec3 mtl = fs(cross(qtr.cell,vec3(4.0,8.0,1.0))); vec3 n = isect.xyz; if (mtl.x<0.1) { col += colRem*vec3(10.0,1.0,1.0); colRem *= 0.0; } else if (mtl.x<0.2) { col += colRem*vec3(6.0,8.0,11.0); colRem *= 0.0; } else { colRem *= 0.3; } ro = ro+rd*rl; rd = mix(uniformLambert(n),reflect(rd,n),pow(random(),0.3)); rl = 0.01; } else { rl += qtr.len; rp = ro+rd*rl; } if (colRem.x<0.01) { ro = ro0; rd = rd0; vec3 fp = ro+rd*2.0; ro += vec3(0.04*vec2(random(),random())*mat2(1.0,1.0,-1.0,1.0),0.0); rd = normalize(fp-ro); rl = 0.01; rp = ro+rd*rl; colRem = vec3(1.0); samples++; } } col = pow(col/samples,vec3(0.4545)); col *= 1.0-0.4*length(p); col = vec3( smoothstep(0.1,0.9,col.x), smoothstep(0.0,1.0,col.y), smoothstep(-0.1,1.1,col.z) ); vec4 prev = vec4(0.0); return mix(vec4(col,1.0),prev,0.5*prev.w); } void main() { vec4 bg_color = drawBackground(); /* vec4 bg_color = vec4(black, 1.0); */ colour_out = drawOrchid(bg_color.xyz); }
Phalaenopsis Hybrid by takuto
// ACG 04 homework: yanagida precision highp float; //out vec4 color_out; uniform float u_time; uniform vec2 u_resolution; const float PI = 3.14159265359; float opSmoothUnion( float d1, float d2, float k ) { float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 ); return mix( d2, d1, h ) - k*h*(1.0-h); } float opSmoothSubtraction( float d1, float d2, float k ) { float h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 ); return mix( d2, -d1, h ) + k*h*(1.0-h); } float opSmoothIntersection( float d1, float d2, float k ) { float h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 ); return mix( d2, d1, h ) + k*h*(1.0-h); } float opUnion( float d1, float d2 ) { return min(d1,d2); } float opSubtraction( float d1, float d2 ) { return max(-d1,d2); } float opIntersection( float d1, float d2 ) { return max(d1,d2); } vec4 qConjugate(vec4 q) { return vec4(-q.x, -q.y, -q.z, q.w); } vec4 qMul(vec4 q1, vec4 q2) { vec3 qv1 = vec3(q1.x, q1.y, q1.z); vec3 qv2 = vec3(q2.x, q2.y, q2.z); return vec4(vec3(cross(qv1, qv2) + q2.w * qv1 + q1.w * qv2), q1.w * q2.w - dot(qv1, qv2)); } vec3 rotate3d(vec3 v, vec4 q) { vec4 vq = vec4(v, 0.0); vec4 cq = qConjugate(q); vec4 qOut = qMul(qMul(cq, vq), q); return vec3(qOut.x, qOut.y, qOut.z); } vec4 makeQuatFromAxisAngle(vec3 axis, float angle) { vec4 quat = vec4(vec3(axis.x * sin(angle / 2.0), axis.y * sin(angle / 2.0), axis.z * sin(angle / 2.0)), cos(angle / 2.0)); return normalize(quat); } float sdEllipsoid( vec3 p, vec3 r ){ float k0 = length(p/r); float k1 = length(p/(r*r)); return k0*(k0-1.0)/k1; } float sdSphere( vec3 p, float s ) { return length(p)-s; } float deg2rad(float deg){ return (PI/180.0)*deg; } float ue(vec3 p){ float ue_fin = 0.0; float ue = sdEllipsoid(p - vec3(0.0, 0.5, 0.0), vec3(0.5,0.9,0.3)); float ue_sub1_r = sdEllipsoid(p - vec3(0.7, 0.0, 0.25), vec3(0.9,1.2,0.4)*0.7); float ue_sub1_l = sdEllipsoid(p - vec3(-0.7, 0.0, 0.25), vec3(0.9,1.2,0.4)*0.7); float ue_sub2 = sdEllipsoid(p - vec3(0.0, 0.6, 0.4), vec3(0.5,0.9,0.2)*1.2); ue_fin = opSmoothSubtraction(ue_sub1_r, ue,0.25); ue_fin = opSmoothSubtraction(ue_sub1_l, ue_fin,0.25); ue_fin = opSmoothSubtraction(ue_sub2, ue_fin,0.1); return ue_fin; } float temae(vec3 p){ float temae = sdEllipsoid(p - vec3(0.0, 0.0, 0.3), vec3(1.2,0.7,0.3)); float temae_sub_1 = sdEllipsoid(p - vec3(0.0, 0.4, 0.3), vec3(0.22,0.4,0.3)); float temae_sub_2 = sdEllipsoid(p - vec3(0.0, -0.4, 0.3), vec3(0.35,0.4,0.3)); vec4 q = makeQuatFromAxisAngle(vec3(0.0,0.0,1.0),deg2rad(150.0)); vec3 tmp = rotate3d(p - vec3(0.6,-0.35, 0.5), q); float temae_r_1 = sdEllipsoid(tmp, vec3(0.3,0.2,0.08)); q = makeQuatFromAxisAngle(vec3(0.0,0.0,1.0),deg2rad(30.0)); tmp = rotate3d(p - vec3(-0.6,-0.35, 0.5), q); float temae_r_2 = sdEllipsoid(tmp, vec3(-0.3,0.2,0.08)); float temae_fin = opSmoothSubtraction(temae_sub_1, temae, 0.2); temae_fin = opSmoothSubtraction(temae_sub_2, temae_fin,0.2); temae_fin = opSmoothSubtraction(temae_r_1, temae_fin, 0.3); temae_fin = opSmoothSubtraction(temae_r_2, temae_fin, 0.3); return temae_fin; } float sdfRep(vec3 p_org, vec3 c){ vec3 p = mod(p_org+0.5*c,c)-0.5*c; float obj = 0.0; float ue_fin = ue(p); float temae_fin = temae(p); vec4 q = makeQuatFromAxisAngle(vec3(0.0,0.1,1.0), deg2rad(140.0)); float sita = ue(rotate3d(p,q)); q = makeQuatFromAxisAngle(vec3(0.0,0.1,1.0),deg2rad(220.0)); float sita2 = ue(rotate3d(p,q)); obj = opUnion(ue_fin, temae_fin); obj = opUnion(sita, obj); obj = opUnion(sita2, obj); return obj; } float mannaka(vec3 p){ float mannaka = sdSphere(p-vec3(0.0,-0.4,0.4), 0.3); float sub = sdSphere(p-vec3(0.0,-0.4,0.5), 0.25); float fin = opSubtraction(sub, mannaka); return fin; } float orchid(vec3 p){ float obj = 0.0; float ue_fin = ue(p); float temae_fin = temae(p); vec4 q = makeQuatFromAxisAngle(vec3(0.0,0.1,1.0), deg2rad(140.0)); float sita = ue(rotate3d(p,q)); q = makeQuatFromAxisAngle(vec3(0.0,0.1,1.0),deg2rad(220.0)); float sita2 = ue(rotate3d(p,q)); float mannnaka = mannaka(p); obj = opUnion(ue_fin, temae_fin); obj = opUnion(sita, obj); obj = opUnion(sita2, obj); obj = opUnion(mannnaka, obj); return obj; } float rand(){ return fract(sin(dot(gl_FragCoord.xy ,vec2(12.9898,78.233))) * 43758.5453); } float distanceFunc(vec3 p){ float obj = sdSphere(p,0.0001 ); //return obj; for(int i=0; i<4; i++){ obj = opUnion(orchid((p- vec3(0.6,-0.9+1.5*float(i),0.0))*1.6), obj); } for(int i=0; i<4; i++){ obj = opUnion(orchid((p- vec3(-0.6,-1.7+1.5*float(i),0.0))*1.8), obj); } for(int i=0; i<4; i++){ obj = opUnion(orchid((p- vec3(1.8,-1.7+1.5*float(i),0.0))*1.6), obj); } for(int i=0; i<4; i++){ obj = opUnion(orchid((p- vec3(-1.8,-0.9+1.5*float(i),0.0))*1.8), obj); } return obj; } vec3 calcNormal(vec3 p){ const float h = 0.0001; const vec2 k = vec2(1,-1); return normalize( k.xyy*distanceFunc( p + k.xyy*h) + \ k.yyx*distanceFunc( p + k.yyx*h) + \ k.yxy*distanceFunc( p + k.yxy*h) + \ k.xxx*distanceFunc( p + k.xxx*h) ); } const vec3 lightDir = vec3(0.0, 0.1, 1.0); void main(void){ // fragment position vec2 p =gl_FragCoord.xy/u_resolution.xy + vec2(-0.5,-0.5); //coord;//(coord * 4.0 - u_resolution) / min(u_resolution.x, u_resolution.y); // camera vec3 cPos = vec3(0.0, 0.0, 2.0); //vec3 cPos = vec3(0.9, 1.0, 5.0); //vec3 cDir = normalize(vec3(-0.5, -0.4, -1.0)); vec3 cDir = normalize(vec3(0.0, 0.0, -1.0)); vec3 cUp = vec3(0.0, 1.0, 0.0); vec3 cSide = cross(cDir, cUp); float targetDepth = 0.3; // ray vec3 ray = normalize(cSide * p.x + cUp * p.y + cDir * targetDepth); // marching loop float distance = 0.0; float rLen = 0.0; vec3 rPos = cPos; for(int i = 0; i < 100; i++){ distance = distanceFunc(rPos); rLen += distance; rPos = cPos + ray * rLen; } // hit check float fog = smoothstep(0.0, 6.0, length(rPos - cPos)); if(abs(distance) < 0.001){ vec3 normal = calcNormal(rPos); vec3 shade = vec3(dot(lightDir, normal)); vec3 layer = mix(shade, normal, 0.2); vec3 mix_temp = mix(vec3(dot(normal, -ray)), layer, 0.8); colour_out = vec4(mix_temp * vec3(1.0,0.6,1.2) + vec3(fog), 1.0); }else{ colour_out = vec4(vec3(0.0), 1.0); } }
Phalaenopsis by yanagida
// credit: s.l uniform vec2 u_resolution; vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } vec4 permute(vec4 x) { return mod289(((x*34.0)+10.0)*x); } vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); // First corner vec3 i = floor(v + dot(v, C.yyy) ); vec3 x0 = v - i + dot(i, C.xxx) ; // Other corners vec3 g = step(x0.yzx, x0.xyz); vec3 l = 1.0 - g; vec3 i1 = min( g.xyz, l.zxy ); vec3 i2 = max( g.xyz, l.zxy ); // x0 = x0 - 0.0 + 0.0 * C.xxx; // x1 = x0 - i1 + 1.0 * C.xxx; // x2 = x0 - i2 + 2.0 * C.xxx; // x3 = x0 - 1.0 + 3.0 * C.xxx; vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y // Permutations i = mod289(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); // Gradients: 7x7 points over a square, mapped onto an octahedron. // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) float n_ = 0.142857142857; // 1.0/7.0 vec3 ns = n_ * D.wyz - D.xzx; vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) vec4 x_ = floor(j * ns.z); vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); vec4 b0 = vec4( x.xy, y.xy ); vec4 b1 = vec4( x.zw, y.zw ); //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; vec4 s0 = floor(b0)*2.0 + 1.0; vec4 s1 = floor(b1)*2.0 + 1.0; vec4 sh = -step(h, vec4(0.0)); vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; vec3 p0 = vec3(a0.xy,h.x); vec3 p1 = vec3(a0.zw,h.y); vec3 p2 = vec3(a1.xy,h.z); vec3 p3 = vec3(a1.zw,h.w); //Normalise gradients vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; p2 *= norm.z; p3 *= norm.w; // Mix final noise value vec4 m = max(0.5 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; return 105.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); } float turbulence( vec3 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( snoise( p * scale ) ) / scale; } return f; } // Blends a pre-multiplied src onto a dst color (without alpha) vec3 premulMix(vec4 src, vec3 dst) { return dst.rgb * (1.0 - src.a) + src.rgb; } // Blends a pre-multiplied src onto a dst color (with alpha) vec4 premulMix(vec4 src, vec4 dst) { vec4 res; res.rgb = premulMix(src, dst.rgb); res.a = 1.0 - (1.0 - src.a) * (1.0 - dst.a); return res; } float sdUnevenCapsule( vec2 p, float r1, float r2, float h ) { p.x = abs(p.x); float b = (r1 - r2) / h; float a = sqrt(1.0 - b * b); float k = dot(p, vec2(-b, a)); if(k < 0.0) return length(p) - r1; if(k > a * h) return length(p - vec2(0.0, h)) - r2; return dot(p, vec2(a, b)) - r1; } float sdVesica(vec2 p, float r, float d) { p = abs(p); float b = sqrt(r * r - d * d); return ((p.y - b) * d > p.x * b) ? length(p - vec2(0.0, b)) : length(p - vec2(-d, 0.0)) - r; } float sdDifference(float d1, float d2) { return max(-d1, d2); } float smax(float a, float b, float k) { float h = max(k - abs(a - b), 0.0); return max(a, b) + h * h * 0.25 / k; } float sdSmoothDifference(float d1, float d2, float k) { return smax(-d1, d2, k); } // The outline of a petal float petalOutline(vec2 p, float s) { vec2 centerLine = vec2(0.5, p.y); // Top if (p.y > 0.6 && p.y < 1.0) return length(p - centerLine) - 0.57 * pow(1.0 - p.y, 0.35) + s; // Middle else if (p.y < 0.6 && p.y > 0.3) return length(p - centerLine) - 0.46 * pow(0.75 - p.y, 0.06) + s; // Bottom else if (p.y < 0.3 && p.y > -0.1) return length(p - centerLine) - 0.3 / (0.832 + exp(- 16.0 * p.y + 2.0)) - 0.1 + s; // Outside else return 1.0; } // Texture of a petal float petalTexture(vec2 p) { p = (p - 0.5) * 30.0; // Strips float n = snoise(p); float strips = smoothstep(0.0, 0.3, sin(p.x * 7.2 * (pow(-0.05 * p.y, 4.0) + 0.25)) + n * 0.25); // Spots n = snoise(p * 0.4); float spots = smoothstep(0.0, 0.1, n); return clamp(strips + spots, 0.0, 1.0); } // Draw a petal with texture vec4 drawPetal(vec2 p) { // White part vec4 whitePart = vec4(1.0 - smoothstep(0.0, 0.01, petalOutline(p, 0.0))); // Pink part vec4 inside = vec4(1.0 - smoothstep(0.0, 0.01, petalOutline(p, 0.033))); inside.rgb *= vec3(0.740,0.132,0.464); // Calculate texture vec4 tex = vec4(petalTexture(p)) * inside; return premulMix(tex, whitePart);; } // Draw the pistil vec4 drawPistil(vec2 p) { vec4 color = vec4(1.0 - sign(sdUnevenCapsule(p, 0.168, 0.124, 0.312))); color.rgb *= vec3(0.983,1.000,0.848); return color; } // Draw small petals vec4 drawSmallPetals(vec2 p) { // A big versica float rad = 1.6; float c = cos(rad), s = sin(rad); float x = 0.3, y = -0.46; mat3 H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; vec2 newP = (H * vec3(p, 1.0)).xy * 5.5; float v = sdVesica(newP, 1.36, 0.2); // Part to be removed 1 rad = 2.96; c = cos(rad), s = sin(rad); x = 0.59, y = 0.13; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part1 = sdVesica(newP, 1.25, 1.0); // Part to be removed 2 rad = 0.104; c = cos(rad), s = sin(rad); x = -0.360, y = -0.272; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part2 = sdVesica(newP, 1.25, 1.0); // Part to be removed 3 rad = 1.6; c = cos(rad), s = sin(rad); x = 0.416, y = -0.456; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; newP = (H * vec3(p, 1.0)).xy * 5.5; float part3 = sdVesica(newP, 1.28, 0.62); // Get small petals by removing the three unwanted parts of the big versica float smallPetals = sdSmoothDifference(part3, sdDifference(part2, sdDifference(part1, v)), 0.2); // Calculate and return the color (The edges are white) vec4 color_inside = vec4(1.0 - smoothstep(0.0, 0.04, smallPetals)); color_inside.rgb *= vec3(0.73 ,0.13,0.46) * (p.y + 0.75); vec4 color_outside = vec4(1.0 - smoothstep(0.02, 0.04, smallPetals)); return premulMix(color_inside, color_outside); } // uniform float u_time; vec4 drawBackground(vec2 p) { // vec3 uv = vec3(p.xy, 0.04 * u_time); vec3 uv = vec3(p.xy, 0.04); float noise = 0.50 * turbulence(uv) + 0.5; return vec4( vec3(0.507,0.800,0.183), noise); } void main() { vec2 st = gl_FragCoord.xy / u_resolution.xy; vec4 background = drawBackground(st); // Adjust the center of the orchid st += vec2(0.0, 0.05); // Draw petal 1 float rad = 0.0; float c = cos(rad), s = sin(rad); float x = -0.352, y = -0.568; mat3 H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; vec2 p = (H * vec3(st, 1.0)).xy * 3.3; vec4 petal1 = drawPetal(p); petal1.rgb *= 1.070 * pow(1.0 - p.y, 0.1); colour_out = premulMix(petal1, background); // Draw petal 2 rad = -2.416; c = cos(rad), s = sin(rad); x = 0.144, y = 0.692; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * vec2(3.5, 3.3); vec4 petal2 = drawPetal(p); petal2.rgb *= 0.9; colour_out = premulMix(petal2, colour_out); // Draw petal 3 rad = 2.360; c = cos(rad), s = sin(rad); x = 0.848, y = -0.016; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * vec2(4.0, 3.3); vec4 petal3 = drawPetal(p); petal3.rgb *= 1.1; colour_out = premulMix(petal3, colour_out); // Draw petal 4 colour_out -= vec4(vec3(0.05), 0.0); rad = 1.640; c = cos(rad), s = sin(rad); x = 0.744, y = -0.504; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 3.0; vec4 petal4 = drawPetal(p); petal4.rgb *= 0.9 * (abs(p.x - 0.5) + 1.0); colour_out = premulMix(petal4, colour_out); // Draw petal 5 rad = -1.464; c = cos(rad), s = sin(rad); x = -0.416, y = 0.408; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 3.0; vec4 petal5 = drawPetal(p); petal5.rgb *= 0.9 * (abs(p.x - 0.5) + 1.0); colour_out = premulMix(petal5, colour_out); // Draw pistil rad = 0.112; c = cos(rad), s = sin(rad); x = -0.432, y = -0.592; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 5.488; vec4 pistil = drawPistil(p); colour_out = premulMix(pistil, colour_out); // Draw small petals rad = 0.112; c = cos(rad), s = sin(rad); x = -0.200, y = -0.448; H = mat3( c, s, 0, -s, c, 0, x, y, 1 ); // vec2 p = (inverse(H) * vec3(st, 1.0)).xy; p = (H * vec3(st, 1.0)).xy * 2.0; vec4 smallPetals = drawSmallPetals(p); colour_out = premulMix(smallPetals, colour_out); // Add some light from the top right corner colour_out += 0.1 * st.x * st.y; }
unknown by s.l
// credit: 5121DG04-3 // orchid: Cymbidium Cultivar uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; // define squared dot product float dot2(in vec2 v){return dot(v,v);} // Primitives____________________________ // Modified from https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm // Vesica float sdVesica(vec2 p, float r, float d){ p = abs(p); float b = sqrt(r*r-d*d); return ((p.y-b)*d>p.x*b) ? length(p-vec2(0.0,b)) : length(p-vec2(-d,0.0))-r; } // Egg float sdEgg( in vec2 p, in float ra, in float rb ){ const float k = sqrt(0.5); p.x = abs(p.x); float r = ra - rb; return ((p.y<0.0) ? length(vec2(p.x, p.y )) - r : (k*(p.x+r)<p.y) ? length(vec2(p.x, p.y-k*r)) : length(vec2(p.x+r,p.y )) - 2.0*r) - rb; } // Uneven Capsule float sdUnevenCapsule( vec2 p, float r1, float r2, float h ){ p.x = abs(p.x); float b = (r1-r2)/h; float a = sqrt(1.0-b*b); float k = dot(p,vec2(-b,a)); if( k < 0.0 ) return length(p) - r1; if( k > a*h ) return length(p-vec2(0.0,h)) - r2; return dot(p, vec2(a,b) ) - r1; } // Structures____________________________ // Petals float petals(vec2 p, float offset){ // Dimensions float petal_length = 0.37; float petal_width_drop = 0.3; // Position vec2 coord = p.xy-offset; // Rotation Matrix float theta = 2.5; float c = cos(theta); float s = sin(theta); mat3 R = mat3(c, -s, 0, s, c, 0, 0, 0, 1.0); // Signed distance function float petals_sdf = sdVesica(coord.xy-vec2(0.0, offset/2.5), petal_length, petal_width_drop); for (int i=0; i<4; i++){ coord = (R*vec3(coord.xy, 1.0)).xy; petals_sdf = min(petals_sdf, sdVesica(coord.xy-vec2(0.0, offset/2.5), petal_length, petal_width_drop)); } return petals_sdf; } // Lip float lip(vec2 p, float offset){ // Dimensions float lip_length = 0.1; float lip_width = 0.05; float stem_bot_rad = 0.03; float stem_top_rad = 0.06; float stem_height = 0.15; // Position vec2 coord = p.xy-offset; // Signed distance function float lip_sdf = min(sdEgg( coord + vec2(0.0, offset/10.0), lip_length, lip_width ), sdUnevenCapsule(coord, stem_bot_rad, stem_top_rad, stem_height)); return lip_sdf; } // Noise___________________________________ // Modified from the lecture slides // Random number generator float rng(vec2 co) { const highp float seed = 12.9898; highp float a = seed; highp float b = 78.233, c = 43758.5453; highp float dt= dot(co.xy, vec2(a,b)); highp float sn= mod(dt,3.14159265358979323846); return fract(sin(sn) * c); } // Noise function float vnoise( vec2 st ) { vec2 i = floor(st), f = fract(st); float a = rng(i), b = rng(i + vec2(1.0, 0.0)), c = rng(i + vec2(0.0, 1.0)), d = rng(i + vec2(1.0, 1.0)); vec2 uv= smoothstep(0.0, 1.0, f); //uv = f; return mix( a, b, uv.x ) + (c-a)*uv.y * (1.0-uv.x) + (d-b)*uv.x*uv.y; } // Brownian motion float fbm( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += vnoise( p * scale ) / scale; } return f; } // Marble Texture float marbleturbulence( vec2 p ) { /* Same as the turbulence before. */ float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += abs( vnoise( p * scale ) ) / scale; } return f; } // Colouring__________________________________ void main() { // Coordinates vec2 st = gl_FragCoord.xy/u_resolution.xy; float offset = 0.5; // Brownian texture float b = fbm( gl_FragCoord.xy / 10.0 ); // Marble texture float n = marbleturbulence( gl_FragCoord.xy / 3.0 ); float t = 1.0 + sin( gl_FragCoord.x / 80.0 + 10.0 * n ) / 2.0; // Orchid outline float orchid_sdf = min(lip(st.xy, offset), petals(st.xy, offset)); // Mask float mask = 1.0; mask *= step(0.0, orchid_sdf); // Petal colour vec3 petal_col = mix(vec3(1.000,0.891,0.000),vec3(1.000,0.680,0.954)-sign(lip(st.xy, offset))*vec3(0.1, 0.4, 0.7), exp(length(st-0.5))); petal_col = mix( vec3(t,0.3,0.5), petal_col, exp(length(st-0.5))); // Lip colour vec3 lip_col = vec3(1.000,0.745,0.950)/b; // Output colour if(lip(st.xy, offset) < 0.0){ colour_out = vec4(lip_col, 1.0); } else{ colour_out = vec4(petal_col, 1.0); } colour_out *= 1.0-mask; }
Cymbidium Cultivar by anonymous
// credit: CGbaby // orchid: Phalaenopsis aphrodite uniform vec2 u_resolution; uniform vec2 u_mouse; uniform float u_time; const float PI = 3.14159265358979324; vec2 rotate(vec2 p, float theta) { return mat2(cos(theta), -sin(theta), sin(theta), cos(theta)) * p; } float dot2(vec2 p) { return dot(p, p); } float add(float d1, float d2) { return min(d1, d2); } // d1 + d2 float diff(float d1, float d2) { return max(d1, -d2); } // d1 - d2 float random(vec2 co) { const highp float seed = 13.9898; highp float a = seed; highp float b = 78.233, c = 43758.5453; highp float dt= dot(co.xy, vec2(a,b)); highp float sn= mod(dt,PI); return fract(sin(sn) * c); } vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } vec3 permute(vec3 x) { return mod289(((x*34.0)+10.0)*x); } float snoise(vec2 v) { const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) -0.577350269189626, // -1.0 + 2.0 * C.x 0.024390243902439); // 1.0 / 41.0 // First corner vec2 i = floor(v + dot(v, C.yy) ); vec2 x0 = v - i + dot(i, C.xx); // Other corners vec2 i1; //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 //i1.y = 1.0 - i1.x; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); // x0 = x0 - 0.0 + 0.0 * C.xx ; // x1 = x0 - i1 + 1.0 * C.xx ; // x2 = x0 - 1.0 + 2.0 * C.xx ; vec4 x12 = x0.xyxy + C.xxzz; x12.xy -= i1; // Permutations i = mod289(i); // Avoid truncation effects in permutation vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 )); vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); m = m*m ; m = m*m ; // Gradients: 41 points uniformly over a line, mapped onto a diamond. // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) vec3 x = 2.0 * fract(p * C.www) - 1.0; vec3 h = abs(x) - 0.5; vec3 ox = floor(x + 0.5); vec3 a0 = x - ox; // Normalise gradients implicitly by scaling m // Approximation of: m *= inversesqrt( a0*a0 + h*h ); m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); // Compute final noise value at P vec3 g; g.x = a0.x * x0.x + h.x * x0.y; g.yz = a0.yz * x12.xz + h.yz * x12.yw; return 130.0 * dot(m, g); } float fbm( vec2 p ) { float f = 0.0, scale; for (int i=0; i<4; i++) { scale = pow( pow(2.0, 4.0/3.0), float(i) ); f += snoise( p * scale ) / scale; } return f; } float sdBezier( in vec2 pos, in vec2 A, in vec2 B, in vec2 C, in float r ) { vec2 a = B - A; vec2 b = A - 2.0*B + C; vec2 c = a * 2.0; vec2 d = A - pos; float kk = 1.0/dot(b,b); float kx = kk * dot(a,b); float ky = kk * (2.0*dot(a,a)+dot(d,b)) / 3.0; float kz = kk * dot(d,a); float res = 0.0; float p = ky - kx*kx; float p3 = p*p*p; float q = kx*(2.0*kx*kx-3.0*ky) + kz; float h = q*q + 4.0*p3; if( h >= 0.0) { h = sqrt(h); vec2 x = (vec2(h,-h)-q)/2.0; vec2 uv = sign(x)*pow(abs(x), vec2(1.0/3.0)); float t = clamp( uv.x+uv.y-kx, 0.0, 1.0 ); res = dot2(d + (c + b*t)*t); } else { float z = sqrt(-p); float v = acos( q/(p*z*2.0) ) / 3.0; float m = cos(v); float n = sin(v)*1.732050808; vec3 t = clamp(vec3(m+m,-n-m,n-m)*z-kx,0.0,1.0); res = min( dot2(d+(c+b*t.x)*t.x), dot2(d+(c+b*t.y)*t.y) ); // the third root cannot be the closest // res = min(res,dot2(d+(c+b*t.z)*t.z)); } return sqrt( res ) - r; } float sdBox( in vec2 p, in vec2 b ) { vec2 d = abs(p)-b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } float sdPieY( in vec2 p, float t, in float r ) { vec2 c = vec2(sin(t), cos(t)); p.y = abs(p.y); float l = length(p) - r; float m = length(p-c*clamp(dot(p,c),0.0,r)); // c=sin/cos of aperture return max(l,m*sign(c.y*p.x-c.x*p.y)); } float sdCircle( vec2 p, float r ) { return length(p) - r; } float sdParabola( in vec2 pos, in float k, bool inv ) { pos.x = abs(pos.x); float ik = 1.0/k; float p = ik*(pos.y - 0.5*ik)/3.0; float q = 0.25*ik*ik*pos.x; float h = q*q - p*p*p; float r = sqrt(abs(h)); float x = (h>0.0) ? pow(q+r,1.0/3.0) - pow(abs(q-r),1.0/3.0)*sign(r-q) : 2.0*cos(atan(r,q)/3.0)*sqrt(p); float sgn = inv ? -1.0 : 1.0; return sgn * length(pos-vec2(x,k*x*x)) * sign(pos.x-x); } float sdHorseshoe( in vec2 p, in float t, in float r, in vec2 w ) { vec2 c = vec2(sin(t), cos(t)); p.x = abs(p.x); float l = length(p); p = mat2(-c.x, c.y, c.y, c.x)*p; p = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), (p.x>0.0)?p.y:l ); p = vec2(p.x,abs(p.y-r))-w; return length(max(p,0.0)) + min(0.0,max(p.x,p.y)); } const int N = 4; float sdRoundedPolygon( in vec2[N] v, in vec2 p, in float r ) { float d = dot(p-v[0],p-v[0]); float s = 1.0; for( int i=0, j=N-1; i<N; j=i, i++ ) { vec2 e = v[j] - v[i]; vec2 w = p - v[i]; vec2 b = w - e*clamp( dot(w,e)/dot(e,e), 0.0, 1.0 ); d = min( d, dot(b,b) ); bvec3 c = bvec3(p.y>=v[i].y,p.y<v[j].y,e.x*w.y>e.y*w.x); if( all(c) || all(not(c)) ) s*=-1.0; } return s*sqrt(d) - r; } float petal(vec2 p) { p.x = abs(p.x - sign(p.x) * 0.005); float d1; d1 = sdPieY(p, 0.97 * PI, 0.5); d1 = diff(d1, sdCircle(p - vec2(-0.2, 0.25), 0.3)); d1 = diff(d1, sdCircle(p - vec2(-0.2, -0.25), 0.3)); float d2; d2 = sdParabola(rotate(p, 0.21 * PI) - vec2(0.364, 0.325), -15.9, true); d2 = diff(d2, sdBox(p - vec2(0, -1.15), vec2(1, 1.5))); float d3; d3 = sdParabola(rotate(p, 0.79 * PI) - vec2(-0.364, 0.325), -15.9, true); d3 = diff(d3, sdBox(p - vec2(0, 1.15), vec2(1, 1.5))); float d; d = diff(d1, d2); d = diff(d, d3); return d; } float petalLine(vec2 p) { p.x = abs(p.x - sign(p.x) * 0.005); float d1; d1 = sdBezier(p, vec2(0.2, 0), vec2(0.3, 0.0001), vec2(0.35, 0), 0.0025); float d2; d2 = sdBezier(p, vec2(0.16, 0.04), vec2(0.16, 0.0401), vec2(0.32, 0.05), 0.002); float d3; d3 = sdBezier(p, vec2(0.16, 0.07), vec2(0.25, 0.10), vec2(0.35, 0.1), 0.002); float d4; d4 = sdBezier(p, vec2(0.18, -0.04), vec2(0.25, -0.07), vec2(0.32, -0.05), 0.002); float d; d = add(d1, d2); d = add(d, d3); d = add(d, d4); return d; } float lip(vec2 p) { float d1; d1 = sdHorseshoe(p - vec2(0, -0.16), 0.1 * PI, 0.07, vec2(0.06, 0.025)); float d2; d2 = sdBox(p - vec2(0, -0.3), vec2(0.07, 0.07)); d2 = diff(d2, sdCircle(p - vec2(0.15, -0.33), 0.12)); d2 = diff(d2, sdCircle(p - vec2(-0.15, -0.33), 0.12)); float d; d = add(d1, d2); return d; } float lipLine(vec2 p) { p.x = abs(p.x); float d1; d1 = sdBezier(p, vec2(0.04, -0.20), vec2(0.055, -0.20), vec2(0.07, -0.18), 0.004); float d2; d2 = sdBezier(p, vec2(0.04, -0.22), vec2(0.055, -0.23), vec2(0.08, -0.21), 0.004); float d; d = add(d1, d2); return d; } float lipProtrusion(vec2 p) { p.x = abs(p.x); float d1; vec2[] v = vec2[]( vec2(0, 0), vec2(0.02, 0.01), vec2(0.01, -0.06), vec2(0, -0.05) ); d1 = sdRoundedPolygon(v, p - vec2(0.01, -0.18), 0.01); float d; d = d1; return d; } float dorsalSepal(vec2 p) { float d1; d1 = sdParabola(p - vec2(0, 0.7), -5.0, false); d1 = diff(d1, sdBox(p - vec2(0, -1.5), vec2(1, 1.5))); float d; //d = d1; d = diff(d1, petal(p)); return d; } float dorsalSepalLine(vec2 p) { float d1; d1 = sdBezier(p, vec2(-0.03, 0.06), vec2(-0.07, 0.18), vec2(-0.08, 0.3), 0.0025); float d2; d2 = sdBezier(p, vec2(-0.01, 0.06), vec2(-0.04, 0.15), vec2(-0.03, 0.3), 0.0025); float d3; d3 = sdBezier(p, vec2(0.01, 0.07), vec2(0.01, 0.15), vec2(0.01, 0.32), 0.0025); float d; d = add(d1, d2); d = add(d, d3); return d; } float lowerSepal(vec2 p) { float d1; d1 = sdParabola(rotate(p, 0.95 * PI) - vec2(0.21, 0.6), -6.9, false); d1 = diff(d1, sdBox(p - vec2(0, 1.48), vec2(1, 1.5))); float d2; d2 = sdParabola(rotate(p, 1.05 * PI) - vec2(-0.21, 0.6), -6.9, false); d2 = diff(d2, sdBox(p - vec2(0, 1.48), vec2(1, 1.5))); float d; d = add(d1, d2); d = diff(d, petal(p)); return d; } void main(){ vec3 color; vec2 coord = (gl_FragCoord.xy / u_resolution.xy * 2.0 - 1.0) / 1.3; float fbmVal = fbm(coord); float dLowerSepal = lowerSepal(coord); float dDorsalSepal = dorsalSepal(coord); float dDorsalSepalLine = dorsalSepalLine(coord); float dPetal = petal(coord); float dPetalLine = petalLine(coord); float dLip = lip(coord); float dLipLine = lipLine(coord); float dLipProtrusion = lipProtrusion(coord); if (dLowerSepal <= .0) { color = vec3(0.88, 0.92, 0.96); float coef = 0.08 * (1.0 - smoothstep(0.0, 0.04, dPetal)); color *= coef * fbmVal + (1.0 - coef); } if (dDorsalSepal <= .0) { color = vec3(0.88, 0.92, 0.96); float coef = 0.08 * (1.0 - smoothstep(0.0, 0.04, dPetal)); color *= coef * fbmVal + (1.0 - coef); } if (dDorsalSepalLine <= .0) { color = vec3(0.87, 0.87, 0.87); } if (dPetal <= .0) { color = vec3(0.93, 0.97, 0.98); if (abs(coord.x) >= 0.2) { color *= 1.0 - 0.03 * smoothstep(-0.10, 0.0, dPetal) * fbm(coord * 30.0); } } if (dPetalLine <= .0) { color = vec3(0.87, 0.87, 0.87); } if (dLip <= .0) { color = mix( mix(vec3(0.80, 0.67, 0), vec3(0.92, 0.96, 0.97), smoothstep(0.05, 0.08, abs(coord.x))), vec3(0.92, 0.96, 0.97), smoothstep(0.00, 0.07, abs(coord.y + 0.21)) ); } if (dLipLine <= .0) { color = vec3(0.55, 0.15, 0.14); } if (dLipProtrusion <= .0) { if (random(coord) >= 0.7) { color = vec3(0); } else { color = vec3(0.80, 0.67, 0); } } colour_out = vec4(color, 1); }
Phalaenopsis Aphrodite by CGbaby