Raymarching
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
| void mainImage( out vec4 fragColor, in vec2 fragCoord ) |
| { |
| vec2 mo = iMouse.xy/iResolution.xy; |
| float time = 32.0 + iTime*1.5; |
| |
| |
| vec3 ta = vec3( 0.25, -0.75, -0.75 ); |
| vec3 ro = ta + vec3( 4.5*cos(0.1*time + 7.0*mo.x), 2.2, 4.5*sin(0.1*time + 7.0*mo.x) ); |
| |
| mat3 ca = setCamera( ro, ta, 0.0 ); |
| |
| vec3 tot = vec3(0.0); |
| vec2 p = (2.0*fragCoord-iResolution.xy)/iResolution.y; |
| |
| |
| const float fl = 2.5; |
| |
| |
| vec3 rd = ca * normalize( vec3(p,fl) ); |
| |
| |
| vec2 px = (2.0*(fragCoord+vec2(1.0,0.0))-iResolution.xy)/iResolution.y; |
| vec2 py = (2.0*(fragCoord+vec2(0.0,1.0))-iResolution.xy)/iResolution.y; |
| vec3 rdx = ca * normalize( vec3(px,fl) ); |
| vec3 rdy = ca * normalize( vec3(py,fl) ); |
| |
| |
| vec3 col = render( ro, rd, rdx, rdy ); |
| |
| |
| |
| |
| |
| col = pow( col, vec3(0.4545) ); |
| |
| tot += col; |
| fragColor = vec4( tot, 1.0 ); |
| } |
| |
| vec3 render( in vec3 ro, in vec3 rd, in vec3 rdx, in vec3 rdy ) |
| { |
| |
| vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3; |
| |
| |
| vec2 res = raycast(ro,rd); |
| float t = res.x; |
| float m = res.y; |
| if( m>-0.5 ) |
| { |
| vec3 pos = ro + t*rd; |
| vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal( pos ); |
| vec3 ref = reflect( rd, nor ); |
| |
| |
| col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) ); |
| float ks = 1.0; |
| |
| if( m<1.5 ) |
| { |
| |
| vec3 dpdx = ro.y*(rd/rd.y-rdx/rdx.y); |
| vec3 dpdy = ro.y*(rd/rd.y-rdy/rdy.y); |
| |
| float f = checkersGradBox( 3.0*pos.xz, 3.0*dpdx.xz, 3.0*dpdy.xz ); |
| col = 0.15 + f*vec3(0.05); |
| ks = 0.4; |
| } |
| |
| |
| float occ = calcAO( pos, nor ); |
| |
| vec3 lin = vec3(0.0); |
| |
| |
| { |
| vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) ); |
| vec3 hal = normalize( lig-rd ); |
| float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); |
| |
| dif *= calcSoftshadow( pos, lig, 0.02, 2.5 ); |
| float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0); |
| |
| lin += col*2.20*dif*vec3(1.30,1.00,0.70); |
| lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks; |
| } |
| |
| { |
| float dif = sqrt(clamp( 0.5+0.5*nor.y, 0.0, 1.0 )); |
| dif *= occ; |
| float spe = smoothstep( -0.2, 0.2, ref.y ); |
| spe *= dif; |
| spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0 ); |
| |
| spe *= calcSoftshadow( pos, ref, 0.02, 2.5 ); |
| lin += col*0.60*dif*vec3(0.40,0.60,1.15); |
| lin += 2.00*spe*vec3(0.40,0.60,1.30)*ks; |
| } |
| |
| { |
| float dif = clamp( dot( nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0 )*clamp( 1.0-pos.y,0.0,1.0); |
| dif *= occ; |
| lin += col*0.55*dif*vec3(0.25,0.25,0.25); |
| } |
| |
| { |
| float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0); |
| dif *= occ; |
| lin += col*0.25*dif*vec3(1.00,1.00,1.00); |
| } |
| |
| col = lin; |
| |
| col = mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ); |
| } |
| |
| return vec3( clamp(col,0.0,1.0) ); |
| } |
| |
| vec2 raycast( in vec3 ro, in vec3 rd ) |
| { |
| vec2 res = vec2(-1.0,-1.0); |
| |
| float tmin = 1.0; |
| float tmax = 20.0; |
| |
| |
| float tp1 = (0.0-ro.y)/rd.y; |
| if( tp1>0.0 ) |
| { |
| tmax = min( tmax, tp1 ); |
| res = vec2( tp1, 1.0 ); |
| } |
| |
| |
| |
| vec2 tb = iBox( ro-vec3(0.0,0.4,-0.5), rd, vec3(2.5,0.41,3.0) ); |
| if( tb.x<tb.y && tb.y>0.0 && tb.x<tmax) |
| { |
| |
| tmin = max(tb.x,tmin); |
| tmax = min(tb.y,tmax); |
| |
| float t = tmin; |
| for( int i=0; i<70 && t<tmax; i++ ) |
| { |
| vec2 h = map( ro+rd*t ); |
| if( abs(h.x)<(0.0001*t) ) |
| { |
| res = vec2(t,h.y); |
| break; |
| } |
| t += h.x; |
| } |
| } |
| |
| return res; |
| } |
| |
| vec2 map( in vec3 pos ) |
| { |
| vec2 res = vec2( pos.y, 0.0 ); |
| |
| |
| if( sdBox( pos-vec3(-2.0,0.3,0.25),vec3(0.3,0.3,1.0) )<res.x ) |
| { |
| res = opU( res, vec2( sdSphere( pos-vec3(-2.0,0.25, 0.0), 0.25 ), 26.9 ) ); |
| res = opU( res, vec2( sdRhombus( (pos-vec3(-2.0,0.25, 1.0)).xzy, 0.15, 0.25, 0.04, 0.08 ),17.0 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(0.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdCappedTorus((pos-vec3( 0.0,0.30, 1.0))*vec3(1,-1,1), vec2(0.866025,-0.5), 0.25, 0.05), 25.0) ); |
| res = opU( res, vec2( sdBoxFrame( pos-vec3( 0.0,0.25, 0.0), vec3(0.3,0.25,0.2), 0.025 ), 16.9 ) ); |
| res = opU( res, vec2( sdCone( pos-vec3( 0.0,0.45,-1.0), vec2(0.6,0.8),0.45 ), 55.0 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 0.0,0.25,-2.0), 0.25, 0.25, 0.1 ), 13.67 ) ); |
| res = opU( res, vec2( sdSolidAngle( pos-vec3( 0.0,0.00,-3.0), vec2(3,4)/5.0, 0.4 ), 49.13 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(1.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdTorus( (pos-vec3( 1.0,0.30, 1.0)).xzy, vec2(0.25,0.05) ), 7.1 ) ); |
| res = opU( res, vec2( sdBox( pos-vec3( 1.0,0.25, 0.0), vec3(0.3,0.25,0.1) ), 3.0 ) ); |
| res = opU( res, vec2( sdCapsule( pos-vec3( 1.0,0.00,-1.0),vec3(-0.1,0.1,-0.1), vec3(0.2,0.4,0.2), 0.1 ), 31.9 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 1.0,0.25,-2.0), vec2(0.15,0.25) ), 8.0 ) ); |
| res = opU( res, vec2( sdHexPrism( pos-vec3( 1.0,0.2,-3.0), vec2(0.2,0.05) ), 18.4 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(-1.0,0.35,-1.0),vec3(0.35,0.35,2.5))<res.x ) |
| { |
| res = opU( res, vec2( sdPyramid( pos-vec3(-1.0,-0.6,-3.0), 1.0 ), 13.56 ) ); |
| res = opU( res, vec2( sdOctahedron( pos-vec3(-1.0,0.15,-2.0), 0.35 ), 23.56 ) ); |
| res = opU( res, vec2( sdTriPrism( pos-vec3(-1.0,0.15,-1.0), vec2(0.3,0.05) ),43.5 ) ); |
| res = opU( res, vec2( sdEllipsoid( pos-vec3(-1.0,0.25, 0.0), vec3(0.2, 0.25, 0.05) ), 43.17 ) ); |
| res = opU( res, vec2( sdHorseshoe( pos-vec3(-1.0,0.25, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.08) ), 11.5 ) ); |
| } |
| |
| |
| if( sdBox( pos-vec3(2.0,0.3,-1.0),vec3(0.35,0.3,2.5) )<res.x ) |
| { |
| res = opU( res, vec2( sdOctogonPrism(pos-vec3( 2.0,0.2,-3.0), 0.2, 0.05), 51.8 ) ); |
| res = opU( res, vec2( sdCylinder( pos-vec3( 2.0,0.14,-2.0), vec3(0.1,-0.1,0.0), vec3(-0.2,0.35,0.1), 0.08), 31.2 ) ); |
| res = opU( res, vec2( sdCappedCone( pos-vec3( 2.0,0.09,-1.0), vec3(0.1,0.0,0.0), vec3(-0.2,0.40,0.1), 0.15, 0.05), 46.1 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.15, 0.0), vec3(0.1,0.0,0.0), vec3(-0.1,0.35,0.1), 0.15, 0.05), 51.7 ) ); |
| res = opU( res, vec2( sdRoundCone( pos-vec3( 2.0,0.20, 1.0), 0.2, 0.1, 0.3 ), 37.0 ) ); |
| } |
| |
| return res; |
| } |
| |
| vec2 opU( vec2 d1, vec2 d2 ) |
| { |
| return (d1.x<d2.x) ? d1 : d2; |
| } |
| |
| float sdPyramid( in vec3 p, in float h ) |
| { |
| float m2 = h*h + 0.25; |
| |
| |
| p.xz = abs(p.xz); |
| p.xz = (p.z>p.x) ? p.zx : p.xz; |
| p.xz -= 0.5; |
| |
| |
| vec3 q = vec3( p.z, h*p.y - 0.5*p.x, h*p.x + 0.5*p.y); |
| |
| float s = max(-q.x,0.0); |
| float t = clamp( (q.y-0.5*p.z)/(m2+0.25), 0.0, 1.0 ); |
| |
| float a = m2*(q.x+s)*(q.x+s) + q.y*q.y; |
| float b = m2*(q.x+0.5*t)*(q.x+0.5*t) + (q.y-m2*t)*(q.y-m2*t); |
| |
| float d2 = min(q.y,-q.x*m2-q.y*0.5) > 0.0 ? 0.0 : min(a,b); |
| |
| |
| return sqrt( (d2+q.z*q.z)/m2 ) * sign(max(q.z,-p.y));; |
| |
| } |
| |
| float sdRhombus(vec3 p, float la, float lb, float h, float ra) |
| { |
| p = abs(p); |
| vec2 b = vec2(la,lb); |
| float f = clamp( (ndot(b,b-2.0*p.xz))/dot(b,b), -1.0, 1.0 ); |
| vec2 q = vec2(length(p.xz-0.5*b*vec2(1.0-f,1.0+f))*sign(p.x*b.y+p.z*b.x-b.x*b.y)-ra, p.y-h); |
| return min(max(q.x,q.y),0.0) + length(max(q,0.0)); |
| } |
| |
| float sdHorseshoe( in vec3 p, in vec2 c, in float r, in float le, vec2 w ) |
| { |
| p.x = abs(p.x); |
| float l = length(p.xy); |
| p.xy = mat2(-c.x, c.y, |
| c.y, c.x)*p.xy; |
| p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x), |
| (p.x>0.0)?p.y:l ); |
| p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0); |
| |
| vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z); |
| vec2 d = abs(q) - w; |
| return min(max(d.x,d.y),0.0) + length(max(d,0.0)); |
| } |
Déplacement du rayon pas à pas