float hash11( float n ) { return fract(sin(n*113.0)*43758.5453123); }
float hash21( vec2 n ) { return fract(sin(dot(n,vec2(1.0,113.0)))*43758.5453123); }
float hash31( vec3 n ) { return fract(sin(dot(n,vec3(1.0,113.0,257.0)))*43758.5453123); }
vec2 hash12( float n ) { return fract(sin(vec2(n,n+1.0))*vec2(43758.5453123,22578.1459123)); }
vec3 hash13( float n ) { return fract(sin(vec3(n,n+2.042,n+12.14))*vec3(43758.5453123,22578.1459123,11271.32862312)); }
float box( vec3 p, vec3 b )
{
return length(max(abs(p)-b,0.0));
}
float getSceneDistance( vec3 pos )
{
float d = pos.y;
d = min( d, box( pos-vec3(15.0, 13.0, 11.0), vec3(4.0,13.0,2.5) ) );
d = min( d, box( pos-vec3(-13.0, 14.0, 11.0), vec3(2.0,14.0,2.5) ) );
d = min( d, box( pos-vec3(-11.0, 12.0, -14.0), vec3(3.0,12.0,2.5) ) );
d = min( d, box( pos-vec3(1.0, 15.0, 1.0), vec3(3.0,3.0,3.0) ) );
return d;
}
float getSpritesDistance( vec3 pos, in float exclude_sprite )
{
float d = 99999.0;
for( float i=0.0; i<20.0; i++ )
{
float t = getUpdateData2i_0( vec2(i, 0.0 ) );
if( i != exclude_sprite )
{
float x = getUpdateData2i_0( vec2(i, 1.0 ) );
float y = getUpdateData2i_0( vec2(i, 2.0 ) );
float z = getUpdateData2i_0( vec2(i, 3.0 ) );
d = min( d, length(pos-vec3(x,y,z))-sprite_radius );
}
}
return d;
}
float distanceFunction2( vec3 pos, in float exclude_sprite )
{
float s = getSpritesDistance( pos, exclude_sprite );
float t = getSceneDistance( pos );
return min( t, s );
}
vec3 getNormal( vec3 pos, in float exclude_sprite )
{
vec3 eps = vec3(.0001,0.0,0.0);
vec3 nor;
nor.x = distanceFunction2(pos+eps.xyy,exclude_sprite) - distanceFunction2(pos-eps.xyy,exclude_sprite);
nor.y = distanceFunction2(pos+eps.yxy,exclude_sprite) - distanceFunction2(pos-eps.yxy,exclude_sprite);
nor.z = distanceFunction2(pos+eps.yyx,exclude_sprite) - distanceFunction2(pos-eps.yyx,exclude_sprite);
return normalize(nor);
}