content/hifi-content/samuel/raymarchWindow2.fs
2022-02-14 02:04:11 +01:00

239 lines
No EOL
7.7 KiB
GLSL

// 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;
}