diff --git a/shader.glsl b/shader.glsl index 3aabec1..86e31ad 100644 --- a/shader.glsl +++ b/shader.glsl @@ -4,6 +4,10 @@ uniform float u_time; uniform sampler2D texture_sampler; uniform sampler2D texts; +mat2 scale(vec2 scale){ + return mat2(scale.x, 0.0, 0.0, scale.y); +} + //////////////////////////////////////////////////////////////// // // HG_SDF @@ -246,8 +250,6 @@ float fCone(vec3 p, float radius, float height) { // //////////////////////////////////////////////////////////////// - - // Rotate around a coordinate axis (i.e. in a plane perpendicular to that axis) by angle . // Read like this: R(p.xz, a) rotates "x towards z". // This is fast if is a compile-time constant and slower (but still practical) if not. @@ -581,6 +583,13 @@ float noise(in vec2 xy, in float seed){ return fract(tan(distance(xy*PHI, xy)*seed)*xy.x); } +vec3 rnd23(vec2 p) +{ + vec3 p3 = fract(p.xyx * vec3(.1031, .1030, .0973)); + p3 += dot(p3, p3.yxz+33.33); + return fract((p3.xxy+p3.yzz)*p3.zyx); +} + mat2 Rot(float a) { float s=sin(a), c=cos(a); return mat2(c, -s, s, c); @@ -588,7 +597,7 @@ mat2 Rot(float a) { vec3 applyFog(in vec3 color, in float distance) { float fogAmount = 1.0 - exp(-distance * 0.01); - vec3 fogColor = vec3(0.17, 0.16, 0.24); + vec3 fogColor = vec3(0.14, 0.13, 0.31); return mix( color, fogColor, fogAmount ); } @@ -613,6 +622,33 @@ float sdCog(vec3 pos, float angle) { return 0.8 * fOpDifferenceRound(d1,d2,0.1)-0.02;} +float sdHex(vec3 pos, float i, float angle) { + vec3 po = pos; + + //po.xy *= Rot(angle); + + pR(po.yz, PI/2.); + //float d1 = opExtrusion(pos, sdCog2d(pos.xy), 0.01); + float d1 = fHexagonIncircle(po, vec2(0.5+i, .1)); + float d2 = fHexagonIncircle(po, vec2(0.2+i, .05)); + return 0.9 * fOpGroove(d1,d2, 0.2,0.2); +} + + +float model(vec3 pos, float angle) { + + float d = 1e10; + + for (float i = 1.; i < 5.; i++) { + vec3 po = pos; + // pos.z += i*.1; + float a = sdHex(po, i*0.2, angle); + + d = min(d,a); + } + + return d; +} // Scene vec2 mapScene(in vec3 p) { float d = 1e10; @@ -620,36 +656,43 @@ vec2 mapScene(in vec3 p) { float dGround = p.y + 1.5; d = min(d, dGround); - float c1 = sdCog(p+vec3(1., 0., 0.), u_time); + vec3 po = p; + //po.y += sin(u_time); + // pMod3(po, vec3(3.)); + + float c1 = model(po, u_time); d = min(d, c1); + - float c2 = sdCog(p+vec3(0.5, -.87, 0.), -u_time); + /*float c2 = sdCog(p+vec3(0.5, -.87, 0.), -u_time); d = min(d, c2); float c3 = sdCog(p+vec3(0.5, .87, 0.), -u_time); d = min(d, c3); - + */ float mat = 0.; if ( d == c1) mat = 1.; - if ( d == c2) mat = 2.; - if ( d == c3) mat = 3.; + //if ( d == c2) mat = 2.; + //if ( d == c3) mat = 3.; return vec2(d, mat); } -vec2 castRay(vec3 ro, vec3 rd) { +vec3 castRay(vec3 ro, vec3 rd) { float t = 0.0; float mat = 0.; + float count = 0.; for(int i=0; i < 100; i++) { vec3 p = ro + rd * t; vec2 res = mapScene(p); t += res.x; mat = res.y; - if (t > 20. || res.x < abs(0.001*t) ) break; + count = float(i); + if (t > 40. || res.x < abs(0.001*t) ) break; } - if (t > 20.) t = -1.0; - return vec2(t, mat); + if (t > 40.) t = -1.0; + return vec3(t, mat, count); } float castShadow(vec3 ro, vec3 rd) { @@ -679,86 +722,94 @@ vec3 fresnel( vec3 F0, vec3 h, vec3 l ) { return F0 + ( 1.0 - F0 ) * pow( clamp( 1.0 - dot( h, l ), 0.0, 1.0 ), 5.0 ); } +vec3 addPointLight(vec3 light_pos, vec3 light_color, float shininess, vec3 v, vec3 dir, vec3 n) { + vec3 Ks = vec3( .5454 ); + vec3 Kd = vec3( 1. ); + vec3 ref = reflect( dir, n ); + vec3 vl = normalize( v ); + vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) ); + vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) ); + vec3 F = fresnel( Ks, normalize( vl - dir ), vl ); + specular = pow( specular, vec3( shininess ) ); + float shadow = castShadow(v + n*0.02, light_pos); + + return light_color * mix( diffuse, specular, F ); +} vec3 shading(vec3 v, vec3 n, vec3 dir, float material) { float shininess = 1.; - vec3 final = vec3( 0.0 ); vec3 ref = reflect( dir, n ); - vec3 Ks = vec3( 0.5 ); - vec3 Kd = vec3( 1.0 ); - vec3 outMaterial = vec3(0.1686, 0.1686, 0.1686); + vec3 outMaterial = vec3(0.1529, 0.1529, 0.1529); if (material == 0.) { - outMaterial = vec3(0.1608, 0.1255, 0.1255); - shininess = 1.; + outMaterial = vec3(0.4, 0.2235, 0.3608); + shininess = 1.5; } else if (material == 1.) { - outMaterial = vec3(0.2039, 0.2431, 0.3137); - shininess = 16.; + outMaterial = vec3(0.8784, 0.8784, 0.8784); + shininess = 15.; } else if (material == 2.) { - outMaterial = vec3(0.0941, 0.102, 0.1137); - shininess = 16.; + outMaterial = vec3(0.0431, 0.2118, 0.4588); + shininess = 1.; } else if (material == 3.) { outMaterial = vec3(0.1569, 0.1922, 0.2549); shininess = 16.; } - - // light 0 - { - vec3 light_pos = vec3( -2.,.3, 10. ); - vec3 light_color = vec3(0.71, 0.51, 0.72) * 5.; - - vec3 vl = normalize( light_pos - v ); - - vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) ); - vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) ); - - vec3 F = fresnel( Ks, normalize( vl - dir ), vl ); - specular = pow( specular, vec3( shininess ) ); - final += outMaterial * specular * light_color * mix( diffuse, specular, F ); - } - - // light 1 - { - vec3 light_pos = vec3( 5.0, 5.0, -20.0 ); - vec3 light_color = vec3(0.14, 0.36, 0.83)* 7.; - - vec3 vl = normalize( light_pos - v ); - - vec3 diffuse = Kd * vec3( max( 0.0, dot( vl, n ) ) ); - vec3 specular = vec3( max( 0.0, dot( vl, ref ) ) ); - - vec3 F = fresnel( Ks, normalize( vl - dir ), vl ); - specular = pow( specular, vec3( shininess ) ); - - final += outMaterial * specular * light_color * mix( diffuse, specular, F ); - } + + vec3 lights = vec3(0.); + lights += addPointLight(vec3( 0.,20., 10. ),vec3(0.38, .54, .54)*2., shininess, v, dir, n); + lights += addPointLight(vec3( 2.0, .0, -10.0 ),vec3(0.22, 0.14, 0.57)*3., shininess, v,dir,n ); + + + vec3 lightDir = vec3(-2. , 3., -1.); + float sun_dif = clamp(dot(n, lightDir), 0., 1.); + float shadow = castShadow(v + n*0.02, lightDir); + lights += vec3(0.0863, 0.102, 0.1059) *sun_dif* shadow; //* mix( vec3(sun_dif), specular, F ) + { - vec3 SUN_DIR = vec3(0. , .4, 1.); - float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.); - float shadow = castShadow(v + n*0.02, SUN_DIR); - final += outMaterial * vec3(1.1,1.2, 1.5) * sun_dif * sun_dif * shadow; - } - { - vec3 SUN_DIR = vec3(0. , .6, -1.); - float sun_dif = clamp(dot(n, SUN_DIR), 0., 1.); - final += outMaterial * vec3(0.0353, 0.2667, 0.4784) * sun_dif; + vec3 lightDir = vec3(0. , .6, -1.); + float sun_dif = clamp(dot(n, lightDir), 0., 1.); + //lights += vec3(0.1804, 0.3686, 0.5451) * sun_dif; } + + //vec3 col = mix(vec3(0.051, 0.0118, 0.1216), vec3(0.2471, 0.3216, 0.0471), v.y); + //lights += col * fresnel(vec3(.5),dir, n); // final += texture( iChannel0, ref ).rgb * fresnel( Ks, n, -dir ); // vec3 col = vec3(0.4)* ref.x; - //vec3 col = vec3(0.0588, 0.0588, 0.1216);// - vec3(0.149, 0.0863, 0.2314) * v.x; - //final += col * fresnel( vec3(.5), ref, -dir ); - return final; + // vec3 col = vec3(0.0588, 0.0588, 0.1216);// - vec3(0.149, 0.0863, 0.2314) * v.x; + // lights += col * fresnel( vec3(.5), ref, -dir ); + + //float ind = clamp( dot( n, normalize(lightDir*vec3(-1.0,.0,-1.0)) ), 0.0, 1.0 ); + //lights += vec3(0.2196, 0.2196, 0.2196) * ind; + + return outMaterial * lights; } -vec3 postProcess(vec3 pos, vec3 col) { - float random = noise(gl_FragCoord.xy, 0.01+u_time); - float random2 = noise(gl_FragCoord.xy, .2+u_time); - // col += 0.1*clamp(vec3(0.5*random, 0.5*random2, 0.5*random), 0.02, 1.); // dither - col = pow( col, vec3(1.0/1.3) ); // gamma +vec3 postProcess(vec3 col) { + // float random = noise(gl_FragCoord.xy, 0.01+u_time); + // float random2 = noise(gl_FragCoord.xy, .2+u_time); + //col += 0.075*clamp(vec3(0.5*random, 0.5*random2, 0.5*random), 0.02, 1.); // dither + + // Normalized pixel coordinates (from 0 to 1) + vec2 screenCoord = gl_FragCoord.xy/u_resolution.xy; + + // Vignette + float radius = 0.9; + float d = smoothstep(radius, radius-0.4, length(screenCoord-vec2(0.5))); + col = mix(col, col * d, 0.6); + + // Contrast + float constrast = .3; + col = mix(col, smoothstep(0.0, 1.0, col), constrast); + + + // Colour mapping + col *= vec3(0.9412, 0.8392, 1.0); + + col = pow( col, vec3(1.0/2.2) ); // gamma // fade in at the beginning - // col*=vec3(clamp((u_time-1.8)*0.5,0., 1.)); + //col*=vec3(clamp((u_time-1.8)*0.5,0., 1.)); // fade out at the end // col*=vec3(clamp((120.-u_time)*.35, 0., 1.)); @@ -766,55 +817,84 @@ vec3 postProcess(vec3 pos, vec3 col) { return col; } -vec3 rnd23(vec2 p) +vec3 getCameraRayDir(vec2 uv, vec3 camPos, vec3 camTarget) { - vec3 p3 = fract(p.xyx * vec3(.1031, .1030, .0973)); - p3 += dot(p3, p3.yxz+33.33); - return fract((p3.xxy+p3.yzz)*p3.zyx); + // Calculate camera's "orthonormal basis", i.e. its transform matrix components + vec3 camForward = normalize(camTarget - camPos); + vec3 camRight = normalize(cross(vec3(0.0, 1.0, 0.0), camForward)); + vec3 camUp = normalize(cross(camForward, camRight)); + float fov = 1.1; + vec3 vDir = normalize(uv.x * camRight + uv.y * camUp + camForward * fov); + return vDir; } -void main() -{ - vec2 p = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y; - float angle = -0.4 +u_time*0.4; - // camera - vec3 ta = vec3(0.0, 0., 1.0); - vec3 ro = ta + vec3(4.*sin(angle), cos(angle), 4.*cos(angle)); // *cos(angle)) - /* - vec3 ww = normalize(ta-ro); - vec3 uu = normalize(cross(ww, vec3(0.,1.0, 0.))); // vec3 = pitch, yaw, pan - vec3 vv = normalize(cross(uu,ww)); - vec3 rd = normalize(p.x * uu + p.y*vv + ww * 1.8); // camera - */ - vec3 cz = normalize(ta-ro); - vec3 cx = normalize(cross(cz, vec3(0.,1.0, 0.))); // vec3 = pitch, yaw, pan - vec3 cy = normalize(cross(cx,cz)); - - - float fov = .3+ta.z*.7; +vec3 getCameraFov(vec2 uv, vec3 camPos,vec3 camTarget) { + vec3 camForward = normalize(camTarget-camPos); + vec3 camRight = normalize(cross(vec3(0.0, 1.0, 0.0), camForward)); + vec3 camUp = normalize(cross(camForward,camRight)); + float fov = 1.1; // Depth of field - // we take a random position in a disk in view space - float dof = .02; - vec2 h = vec2( noise(gl_FragCoord.xy, u_time), noise(gl_FragCoord.xy, .1+u_time))*.9; - vec3 voff = sqrt(h.x)*(cx*sin(h.y*6.283)+cy*cos(h.y*6.283))*dof; - ro-=voff; - float focusdistance = 1.5*abs(sin(u_time)+1.); // change what needs to be - vec3 rd=normalize(p.x*cx+p.y*cy+fov*cz + voff*fov/focusdistance); + float dof = .1; + vec2 h = vec2( noise(gl_FragCoord.xy, .11), noise(gl_FragCoord.xy, .4)); + //vec3 h= rnd23(gl_FragCoord.xy); + vec3 voff = sqrt(h.x)*(camRight*sin(h.y*6.283)+camUp*cos(h.y*6.283))*dof; + camTarget -=voff; + float focusdistance = 40.2; + return normalize(uv.x * camRight + uv.y * camUp + fov * camForward + voff * fov/focusdistance); +} - - // global light - vec3 col = vec3(0.1451, 0.1098, 0.1608) - vec3(0.9725, 0.5176, 0.0) *rd.y; - vec2 t = castRay(ro, rd); +vec3 getSceneColor(vec2 fragCoord) { - vec3 pos = ro + rd * t.x; + bool useDof = !true; + //vec2 uv = (2.0 * gl_FragCoord.xy - u_resolution.xy) / u_resolution.y; + vec2 uv = 2.0 * (fragCoord.xy/u_resolution.xy - 0.5); + uv.x *= u_resolution.x/u_resolution.y; // Correct for aspect ratio + + float angle = -2.4 +u_time*0.4; + //angle = 0.; + + // camera + vec3 camPos = vec3(2.*sin(angle), 1.,-2.*cos(angle)); + vec3 camTarget = vec3(0., 0.0, 0.); + vec3 rayDir; + if (useDof) { + rayDir = getCameraFov(uv, camPos, camTarget); + } else { + rayDir = getCameraRayDir(uv, camPos, camTarget); + } + + vec3 col = mix(vec3(0.0824, 0.0275, 0.1882), vec3(0.2471, 0.3216, 0.0471), rayDir.y); + //vec3 col = vec3(0.0314, 0.0118, 0.1255) + rayDir.y * 0.4; + vec3 t = castRay(camPos, rayDir); + + vec3 pos = camPos + rayDir * t.x; if (t.x > 0.) { vec3 nor = calcNormal(pos); - col = shading(pos, nor, rd , t.y); + col = shading(pos, nor, rayDir , t.y); // apply fog col = applyFog(col, t.x); } - col = postProcess(pos, col); - gl_FragColor = vec4( col , 1.0 ); + return col; +} + +void main() +{ + vec2 uv = gl_FragCoord.xy; + vec3 finalColor = vec3(0.); + const float AA_SIZE = 4.; + float count = 0.0; + for (float aaY = 0.0; aaY < AA_SIZE; aaY++) { + for (float aaX = 0.0; aaX < AA_SIZE; aaX++) { + finalColor += getSceneColor(uv + vec2(aaX, aaY) / AA_SIZE); + count += 1.0; + } + } + finalColor /= count; + + finalColor = postProcess(finalColor); + + gl_FragColor = vec4(finalColor, 1.); + } \ No newline at end of file