// Credit to iq: https://www.shadertoy.com/view/4dfGzs // // Slight modifications by Sam Gondelman on 6/9/2016 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // uniform float yOffset = 50.0; float hash(float n) { return fract(sin(n)*753.5453123); } float noise(vec3 xyz) { int seed = 236; vec3 p = floor(xyz); vec3 f = fract(xyz); f = f*f*(3.0-2.0*f); float n = dot(vec4(p, seed), vec4(1, 433, 157, 141)); return mix(mix(mix(hash(n+ 0.0), hash(n+ 1.0),f.x), mix(hash(n+157.0), hash(n+158.0),f.x),f.z), mix(mix(hash(n+433.0), hash(n+434.0),f.x), mix(hash(n+590.0), hash(n+591.0),f.x),f.z), f.y); } float mapTerrain( vec3 p ) { p *= 0.1; p.xz *= 0.6; float time = 0.5 + 0.15*iGlobalTime; float ft = fract( time ); float it = floor( time ); ft = smoothstep( 0.7, 1.0, ft ); time = it + ft; float spe = 1.4; float f; f = 0.5000*noise( p*1.00 + vec3(0.0,1.0,0.0)*spe*time ); f += 0.2500*noise( p*2.02 + vec3(0.0,2.0,0.0)*spe*time ); f += 0.1250*noise( p*4.01 ); return 25.0*f-10.0; } vec3 gro = vec3(0.0); float map(in vec3 c) { vec3 p = c + 0.5; float f = mapTerrain( p ) + 0.25*p.y; f = mix( f, 1.0, step( length(gro-p), 5.0 ) ); return step( f, 0.5 ); } vec3 lig = normalize( vec3(-0.4,0.3,0.7) ); float castRay( in vec3 ro, in vec3 rd, out vec3 oVos, out vec3 oDir ) { vec3 pos = floor(ro); vec3 ri = 1.0/rd; vec3 rs = sign(rd); vec3 dis = (pos-ro + 0.5 + rs*0.5) * ri; float res = -1.0; vec3 mm = vec3(0.0); for( int i=0; i<128; i++ ) { if( map(pos)>0.5 ) { res=1.0; break; } mm = step(dis.xyz, dis.yxy) * step(dis.xyz, dis.zzx); dis += mm * rs * ri; pos += mm * rs; } vec3 nor = -mm*rs; vec3 vos = pos; // intersect the cube vec3 mini = (pos-ro + 0.5 - 0.5*vec3(rs))*ri; float t = max ( mini.x, max ( mini.y, mini.z ) ); oDir = mm; oVos = vos; return t*res; } vec3 path( float t, float ya ) { vec2 p = 100.0*sin( 0.02*t*vec2(1.0,1.2) + vec2(0.1,0.9) ); p += 50.0*sin( 0.04*t*vec2(1.3,1.0) + vec2(1.0,4.5) ); return vec3( p.x, 18.0 + ya*4.0*sin(0.05*t), p.y ); } vec3 render( in vec3 ro, in vec3 rd ) { vec3 col = vec3(0.0); // raymarch vec3 vos, dir; float t = castRay( ro, rd, vos, dir ); if( t>0.0 ) { vec3 nor = -dir*sign(rd); vec3 pos = ro + rd*t; vec3 uvw = pos - vos; vec3 v1 = vos + nor + dir.yzx; vec3 v2 = vos + nor - dir.yzx; vec3 v3 = vos + nor + dir.zxy; vec3 v4 = vos + nor - dir.zxy; vec3 v5 = vos + nor + dir.yzx + dir.zxy; vec3 v6 = vos + nor - dir.yzx + dir.zxy; vec3 v7 = vos + nor - dir.yzx - dir.zxy; vec3 v8 = vos + nor + dir.yzx - dir.zxy; vec3 v9 = vos + dir.yzx; vec3 v10 = vos - dir.yzx; vec3 v11 = vos + dir.zxy; vec3 v12 = vos - dir.zxy; vec3 v13 = vos + dir.yzx + dir.zxy; vec3 v14 = vos - dir.yzx + dir.zxy ; vec3 v15 = vos - dir.yzx - dir.zxy; vec3 v16 = vos + dir.yzx - dir.zxy; vec4 ed = vec4( map(v1), map(v2), map(v3), map(v4) ); vec4 co = vec4( map(v5), map(v6), map(v7), map(v8) ); vec4 ep = vec4( map(v9), map(v10), map(v11), map(v12) ); vec4 cp = vec4( map(v13), map(v14), map(v15), map(v16) ); vec2 uv = vec2( dot(dir.yzx, uvw), dot(dir.zxy, uvw) ); // wireframe vec4 ee = 1.0-ep*(1.0-ed); float www = 1.0; www *= 1.0 - smoothstep( 0.85, 0.99, uv.x )*ee.x; www *= 1.0 - smoothstep( 0.85, 0.99, 1.0-uv.x )*ee.y; www *= 1.0 - smoothstep( 0.85, 0.99, uv.y )*ee.z; www *= 1.0 - smoothstep( 0.85, 0.99, 1.0-uv.y )*ee.w; www *= 1.0 - smoothstep( 0.85, 0.99, uv.y* uv.x )*(1.0-cp.x*(1.0-co.x))*(1.0-ee.x)*(1.0-ee.z); www *= 1.0 - smoothstep( 0.85, 0.99, uv.y* (1.0-uv.x))*(1.0-cp.y*(1.0-co.y))*(1.0-ee.y)*(1.0-ee.z); www *= 1.0 - smoothstep( 0.85, 0.99, (1.0-uv.y)*(1.0-uv.x))*(1.0-cp.z*(1.0-co.z))*(1.0-ee.y)*(1.0-ee.w); www *= 1.0 - smoothstep( 0.85, 0.99, (1.0-uv.y)* uv.x )*(1.0-cp.w*(1.0-co.w))*(1.0-ee.x)*(1.0-ee.w); vec3 wir = smoothstep( 0.4, 0.5, abs(uvw-0.5) ); float vvv = (1.0-wir.x*wir.y)*(1.0-wir.x*wir.z)*(1.0-wir.y*wir.z); col = 2.0*vec3(0.5); col += 0.8*vec3(0.1,0.3,0.4); col *= 0.5 + 0.5*vec3(0.5); col *= 1.0 - 0.75*(1.0-vvv)*www; // lighting float dif = clamp( dot( nor, lig ), 0.0, 1.0 ); float bac = clamp( dot( nor, normalize(lig*vec3(-1.0,0.0,-1.0)) ), 0.0, 1.0 ); float sky = 0.5 + 0.5*nor.y; float amb = clamp(0.75 + pos.y/25.0,0.0,1.0); float occ = 1.0; // ambient occlusion occ = 0.0; // (for edges) occ += ( uv.x) * ed.x; occ += (1.0-uv.x) * ed.y; occ += ( uv.y) * ed.z; occ += (1.0-uv.y) * ed.w; // (for corners) occ += ( uv.y * uv.x ) * co.x*(1.0-ed.x)*(1.0-ed.z); occ += ( uv.y *(1.0-uv.x)) * co.y*(1.0-ed.z)*(1.0-ed.y); occ += ( (1.0-uv.y)*(1.0-uv.x)) * co.z*(1.0-ed.y)*(1.0-ed.w); occ += ( (1.0-uv.y)* uv.x ) * co.w*(1.0-ed.w)*(1.0-ed.x); occ = 1.0 - occ/8.0; occ = occ*occ; occ = occ*occ; occ *= amb; // lighting vec3 lin = vec3(0.0); lin += 2.5*dif*vec3(1.00,0.90,0.70)*(0.5+0.5*occ); lin += 0.5*bac*vec3(0.15,0.10,0.10)*occ; lin += 2.0*sky*vec3(0.40,0.30,0.15)*occ; // line glow float lineglow = 0.0; lineglow += smoothstep( 0.4, 1.0, uv.x )*(1.0-ep.x*(1.0-ed.x)); lineglow += smoothstep( 0.4, 1.0, 1.0-uv.x )*(1.0-ep.y*(1.0-ed.y)); lineglow += smoothstep( 0.4, 1.0, uv.y )*(1.0-ep.z*(1.0-ed.z)); lineglow += smoothstep( 0.4, 1.0, 1.0-uv.y )*(1.0-ep.w*(1.0-ed.w)); lineglow += smoothstep( 0.4, 1.0, uv.y* uv.x )*(1.0-cp.x*(1.0-co.x)); lineglow += smoothstep( 0.4, 1.0, uv.y* (1.0-uv.x))*(1.0-cp.y*(1.0-co.y)); lineglow += smoothstep( 0.4, 1.0, (1.0-uv.y)*(1.0-uv.x))*(1.0-cp.z*(1.0-co.z)); lineglow += smoothstep( 0.4, 1.0, (1.0-uv.y)* uv.x )*(1.0-cp.w*(1.0-co.w)); vec3 linCol = 2.0*vec3(5.0,0.6,0.0); linCol *= (0.5+0.5*occ)*0.5; lin += 3.0*lineglow*linCol; col = col*lin; col += 8.0*linCol*vec3(1.0,2.0,3.0)*(1.0-www);//*(0.5+1.0*sha); col += 0.1*lineglow*linCol; col *= min(0.1,exp( -0.07*t )); // blend to black & white vec3 col2 = vec3(1.3)*(0.5+0.5*nor.y)*occ*www*(0.9+0.1*vvv)*exp( -0.04*t );; float mi = sin(-1.57+0.5*iGlobalTime); mi = smoothstep( 0.90, 0.95, mi ); col = mix( col, col2, mi ); } // gamma col = pow( col, vec3(0.45) ); return col; } vec4 getProceduralColor() { vec3 worldEye = getEyeWorldPos(); vec3 ro = iWorldOrientation * (_position.xyz * iWorldScale) + iWorldPosition; // world position of the current fragment vec3 eye = worldEye; // make sure the object is never inside a block ro.y += yOffset; eye.y += yOffset; vec3 rd = normalize(ro - eye); // ray from camera eye to ro return vec4(render(eye, rd), 1.0); } float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) { vec4 color = getProceduralColor(); diffuse = color.rgb; specular = color.rgb; shininess = 0.5; return 1.0; }