// Created by inigo quilez - iq/2014 // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. //#define HIGH_QUALITY_NOISE float noise( in vec2 x ) { vec2 p = floor(x); vec2 f = fract(x); f = f*f*(3.0-2.0*f); #ifdef HIGH_QUALITY_NOISE float a = textureLod( iChannel0, (p+vec2(0.5,0.5))/256.0, 0.0 ).x; float b = textureLod( iChannel0, (p+vec2(1.5,0.5))/256.0, 0.0 ).x; float c = textureLod( iChannel0, (p+vec2(0.5,1.5))/256.0, 0.0 ).x; float d = textureLod( iChannel0, (p+vec2(1.5,1.5))/256.0, 0.0 ).x; return -1.0 + 2.0*mix( mix(a,b,f.x), mix(c,d,f.x), f.y ); #else return -1.0 + 2.0*textureLod( iChannel0, (p+f+0.5)/256.0, 0.0 ).x; #endif } vec2 sd2Segment( vec3 a, vec3 b, vec3 p ) { vec3 pa = p - a; vec3 ba = b - a; float t = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); vec3 v = pa - ba*t; return vec2( dot(v,v), t ); } float udBox(vec3 p, vec3 b) { return length(max(abs(p)-b, 0.0)); } float udRoundBox( vec3 p, vec3 b, float r ) { return length(max(abs(p)-b,0.0))-r; } float smin( float a, float b, float k ) { float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); return mix( b, a, h ) - k*h*(1.0-h); } //----------------------------------------------------------------------------------- #define NUMI 11 #define NUMF 11.0 vec3 fishPos; float fishTime; float isJump; float isJump2; vec2 anima( float ih, float t ) { float an1 = 0.9*(0.5+0.2*ih)*cos(5.0*ih - 3.0*t + 6.2831/4.0); float an2 = 1.0*cos(3.5*ih - 1.0*t + 6.2831/4.0); float an = mix( an1, an2, isJump ); float ro = 0.4*cos(4.0*ih - 1.0*t)*(1.0-0.5*isJump); return vec2( an, ro ); } vec3 anima2( void ) { vec3 a1 = vec3(0.0, sin(3.0*fishTime+6.2831/4.0),0.0); vec3 a2 = vec3(0.0,1.5+2.5*cos(1.0*fishTime),0.0); vec3 a = mix( a1, a2, isJump ); a.y *= 0.5; a.x += 0.1*sin(0.1 - 1.0*fishTime)*(1.0-isJump); return a; } vec2 sdDolphinCheap( vec3 p ) { vec2 res = vec2( 1000.0, 0.0 ); p -= fishPos; vec3 a = anima2(); float or = 0.0; float th = 0.0; float hm = 0.0; vec3 mp = a; for( int i=0; iprecis && tmaxd ) break; { t += h; vec2 res = sdDolphin( ro+rd*t ); h = res.x; l = res.y; } } if( t>maxd ) t=-1.0; return vec2( t, l); } vec3 intersectWater( vec3 ro, in vec3 rd ) { const float precis = 0.001; float h = precis*3.0; float l = 0.0; float s = 0.0; float t = (2.5-ro.y)/rd.y; if( t<0.0 ) return vec3(-1.0); for( int i=0; i<12; i++ ) { if( h0.001 ) sha=softshadow( pos+0.01*nor, lig, 0.0005, 32.0 ); float fre = pow( clamp( 1.0 + dot(nor,rd), 0.0, 1.0 ), 5.0 ); float spe = max( 0.0, pow( clamp( dot(lig,ref), 0.0, 1.0), 0.01+glossy ) ) * glossy; float sss = pow( clamp( 1.0 + dot(nor,rd), 0.0, 1.0 ), 3.0 ); // lights vec3 brdf = vec3(0.0); brdf += 8.0*dif*vec3(1.80,1.35,0.90)*vec3(sha,sha*0.5+0.5*sha*sha,sha*sha); brdf += 1.0*sky*vec3(0.20,0.40,0.55)*occ; brdf += 1.0*bac*vec3(0.40,0.60,0.70)*occ; brdf += 1.0*bou*vec3(0.10,0.20,0.25); brdf += 1.0*sss*vec3(0.40,0.40,0.40)*(0.3+0.7*dif*sha)*glossy*occ; brdf += 0.5*spe*vec3(1.3,1.0,0.8)*sha*(0.3+0.7*fre)*occ*glossy; brdf += glossy*0.3*vec3(0.8,0.9,1.0)*occ*smoothstep( 0.0, 0.2, ref.y )*(0.5+0.5*smoothstep( 0.0, 1.0, ref.y ));//*smoothstep(-0.1,0.0,dif); col = col*brdf; col += (0.5 + 1.5*fre)*occ*glossy2*glossy2*10.0*vec3(1.0,0.9,0.8)*smoothstep( 0.0, 0.2, ref.y )*(0.5+0.5*smoothstep( 0.0, 1.0, ref.y ));//*smoothstep(-0.1,0.0,dif); col += 0.25*glossy*pow(spe/(0.01+glossy),8.0)*vec3(1.3,1.0,0.8)*sha*(0.3+0.7*fre)*occ; return col; } vec3 normalMap( in vec2 pos ) { pos *= 6.0; pos.y *= 0.375; float v = texture( iChannel2, 0.015*pos ).x; vec3 nor = vec3( texture( iChannel2, 0.015*pos+vec2(1.0/1024.0,0.0)).x - v, 1.0/16.0, texture( iChannel2, 0.015*pos+vec2(0.0,1.0/1024.0)).x - v ); nor.xz *= -1.0; return normalize( nor ); } #define gl_NormalMatrix mat3(transpose(inverse(getTransformCamera()._view))) #define gl_ModelViewMatrix getTransformCamera()._view #define gl_ModelViewMatrixInverse getTransformCamera()._viewInverse #define gl_ProjectionMatrix getTransformCamera()._projection #define gl_ProjectionMatrixInverse getTransformCamera()._projectionInverse void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 q = fragCoord.xy / iResolution.xy; vec2 p = -1.0 + 2.0 * q; p.x *= iResolution.x/iResolution.y; vec2 m = vec2(0.5); if( iMouse.z>0.0 ) m = iMouse.xy/iResolution.xy; //----------------------------------------------------- // animate //----------------------------------------------------- fishTime = 0.6 + 2.0*iGlobalTime - 20.0; fishPos = vec3( 0.0, 0.0-0.2, -1.1*fishTime ); isJump = 0.5 + 0.5*cos( -0.4+0.5*fishTime); isJump2 = 0.5 + 0.5*cos( 0.6+0.5*fishTime); float isJump3 = 0.5 + 0.5*cos(-1.4+0.5*fishTime); //----------------------------------------------------- // camera //----------------------------------------------------- float an = 1.2 + 0.1*iGlobalTime - 12.0*(m.x-0.5); vec3 ta = vec3(fishPos.x,0.8,fishPos.z) - vec3(0.0,0.0,-2.0); vec3 ro = ta + vec3(4.0*sin(an),3.1,4.0*cos(an)); // shake ro += 0.05*sin(4.0*iGlobalTime*vec3(1.1,1.2,1.3)+vec3(3.0,0.0,1.0) ); ta += 0.05*sin(4.0*iGlobalTime*vec3(1.7,1.5,1.6)+vec3(1.0,2.0,1.0) ); // camera matrix vec3 ww = normalize( ta - ro ); ww = normalize(vec3(0,-1.0,0) * (mat3(gl_ModelViewMatrix * mat4(iWorldOrientation)))); //inverse(iWorldOrientation * inverse(gl_NormalMatrix)); vec3 uu = normalize( cross(ww,vec3(0.0,-1.0,0.0) ) ); //vec3 uu = normalize( vec3(-ww.z,0,ww.x) ); vec3 vv = normalize( cross(ww, uu)); ///vec3 uu = normalize( vec3(-ww.z,0.0,ww.x) ); ///vec3 vv = normalize( cross(uu,ww)); // create view ray vec3 rd = normalize( p.x*uu + p.y*vv + 2.0*ww);// + 2.0*ww*(1.0+0.7*smoothstep(-0.4,0.4,sin(0*0.34*iGlobalTime))) ); //----------------------------------------------------- // render //----------------------------------------------------- float t = 1000.0; vec3 col = vec3(0.0); vec3 bgcol = vec3(0.6,0.7,0.8) - .2*clamp(rd.y,0.0,1.0); // quick step till y=3 bounding plane float pt = (3.0-ro.y)/rd.y; if( rd.y<0.0 && pt>0.0 ) ro=ro+rd*pt; // raymarch vec2 tmat1 = intersectDolphin(ro,rd); vec3 posy = vec3(-100000.0); if( tmat1.x>0.0 ) { vec2 tmat = tmat1; t = tmat.x; // geometry vec3 pos = ro + tmat.x*rd; vec3 nor = calcNormalFish(pos); vec3 ref = reflect( rd, nor ); vec3 fpos = pos - fishPos; vec3 auu = normalize( vec3(-ccd.z,0.0,ccd.x) ); vec3 avv = normalize( cross(ccd,auu) ); vec3 ppp = vec3( dot(fpos-ccp,auu), dot(fpos-ccp,avv), tmat.y ); vec2 uv = vec2( 1.0*atan(ppp.x,ppp.y)/3.1416, 4.0*ppp.z ); vec3 bnor = -1.0+2.0*texture(iChannel0,uv).xyz; nor += 0.01*bnor; vec3 te = texture( iChannel2, uv ).xyz; vec4 mate; mate.w = 17.0; mate.xyz = mix( vec3(0.3,0.35,0.4), vec3(0.8,0.85,0.9)*0.9, 0.8*smoothstep(-0.05,0.05,ppp.y) );; mate.xyz *= 1.0 + 0.3*te; mate.xyz *= smoothstep( 0.0, 0.06, distance(vec3(abs(ppp.x),ppp.yz)*vec3(1.0,1.0,4.0),vec3(0.35,0.0,0.4)) ); mate.xyz *= 1.0 - 0.75*(1.0-smoothstep( 0.0, 0.02, abs(ppp.y) ))*(1.0-smoothstep( 0.07, 0.11, tmat.y )); mate.xyz *= 0.1*0.23; mate.w *= (0.7+0.3*te.x)*smoothstep( 0.0, 0.01, pos.y-sdWaterCheap( pos ) ); // surface-light interacion col = doLighting( pos, nor, rd, mate.w, 0.0, 0.0, mate.xyz, 1.0 ); posy = pos; } vec3 tmat2 = intersectWater(ro,rd); vec3 col2 = vec3(0.0); if( tmat2.x>0.0 && (tmat1.x<0.0 || tmat2.x