uniform sampler2D tDiffuse;
uniform float iTime;
uniform vec2 iResolution;
uniform vec2 iMouse;
uniform vec3 rayOrigin;
uniform vec3 lookAt;
varying vec2 sv;
vec3 round(vec3 value)
{
return floor(value +0.5);
}
vec3 modulo(vec3 x, vec3 y)
{
return x - y * floor(x/y);
}
mat2 Rot(float a) {
float s = sin(a);
float c = cos(a);
return mat2(c, -s, s, c);
}
vec3 opRepLim(vec3 p, float c, vec3 l)
{
return p-c*clamp(round(p/c),-l,l);
}
vec3 opRep( in vec3 p, in vec3 c)
{
return mod(p+0.5*c,c)-0.5*c;
}
float sdSphere( vec3 p, float s )
{
return length(p)-s;
}
float sdGyroid1( vec3 p, float scale, float thickness)
{
p *= scale;
return abs(dot(sin(p) * sin(p.zyx), cos(p.zxy)) - 15.0*thickness)/scale - 0.5*thickness;
return abs(dot(sin(p), cos(p.zxy)) - thickness)/scale - thickness;
//return dot(sin(p) * cos(p.xzy), cos(p.xzy))
return dot(sin(p), cos(p.zxy))/scale;
}
float map( in vec3 pos)
{
// ball
vec3 cen = vec3( 0.0, 0.0, 0.0 );
vec3 repSpherePos = opRep(pos, vec3(2.6, 2.6, 2.6));
float d1 = sdSphere( repSpherePos - cen, 1.5);
float d2 = sdGyroid1(pos, 10.0, 0.1);
float d3 = 2.0 * sdGyroid1(pos, 10.0, 0.1);
d2 = max(d2, d3);
//wdreturn d1;
//return d2;
return max(-d1, d2);
}
#define MAX_STEPS 200; //Dosnt work, rewrite manualy
#define SURFACE_DIST 0.001;
#define MAX_DIST 100.0;
#define MIN_DIST 0.2;
vec3 SUN_COL = vec3(1.0,0.9,0.7);
vec3 FOG_COL = vec3(0.00,0.0,0.00);
vec3 SONNAR_COL = vec3(0.8, 0.1, 0.1);
float castRay( in vec3 ro, in vec3 rd)
{
float tmin = MIN_DIST;
float tmax = MAX_DIST;
float surfDistMin = SURFACE_DIST;
float t = tmin;
for( int i=0; i<150; i++ )
{
float h = map( ro+rd*t);
//abs increases stability non euklidian mapping after the reymarch steps into
//the sdf. the "* t" increases the mistake for farther objects.
if( abs(h)tmax ) t=-1.0;
return t;
}
vec3 palette( in float t, in vec3 a, in vec3 b, in vec3 c, in vec3 d )
{
return a + b*cos( 6.28318*(c*t+d) );
}
vec3 calcNormal( in vec3 pos)
{
vec2 e = vec2(0.0005,0.0);
return normalize( vec3(
map( pos + e.xyy) - map( pos - e.xyy),
map( pos + e.yxy) - map( pos - e.yxy),
map( pos + e.yyx) - map( pos - e.yyx) ) );
}
vec3 getLight(vec3 pos, vec3 lightPos, vec3 normal)
{
vec3 lightDir = normalize(lightPos - pos);
//vec3 normal = calcNormal(pos);
float diffuseLight = clamp(dot(normal, lightDir), 0.0 , 1.);
return diffuseLight * SUN_COL;
}
//Returns the RayDirection for a pixel given the ray origin, the look at vector and a zoom factor.
vec3 cameraRayDirection(vec2 uv, vec3 rayOrigin, vec3 lookAt, float zoom)
{
vec3 forwardDir = normalize(lookAt - rayOrigin);
vec3 rightDir = normalize(cross(vec3(0, 1, 0), forwardDir));
vec3 upDir = cross(forwardDir, rightDir);
vec3 centerOfScreen = rayOrigin + forwardDir * zoom;
vec3 intersectionOfScreen = centerOfScreen + uv.x * rightDir + uv.y * upDir;
return intersectionOfScreen - rayOrigin;
}
vec3 applyFog( in vec3 rgb, // original color of the pixel
in float distance ) // camera to point distance
{
float fogAmount = 1.0 - exp( -distance*0.25 );
vec3 fogColor = vec3(0.7,0.5,0.4);
return mix( rgb, fogColor, fogAmount );
}
vec3 applyFog( in vec3 rgb, // original color of the pixel
in float distance, // camera to point distance
in vec3 rayDir, // camera to point vector
in vec3 sunDir,
in vec3 fogCol ) // sun light direction
{
float fogAmount = 1.0 - exp( -distance*0.25 );
float sunAmount = max( dot( rayDir, sunDir ), 0.0);
vec3 fogColor = mix( fogCol, // bluish
SUN_COL, // yellowish
pow(sunAmount,6.0) );
return mix( rgb, fogColor, fogAmount );
}
vec3 render(vec2 uv)
{
// vec3 rayOrigin = vec3(0, 0.0, 0.0);
// vec3 lookAt = vec3(1.0, 0.0, 0);
//lookAt.yz *= Rot(-iMouse.y*3.14 + 1.57);
// lookAt.xz *= Rot(-iMouse.x*6.2831);
// lookAt.y = (iMouse.y - 0.5)*6.2831;
vec3 lightPos = vec3(-5.0, 10.0, -5.0);
vec3 rayDirection = cameraRayDirection(uv, rayOrigin, lookAt, 1.);
float dist = castRay(rayOrigin, rayDirection);
vec3 pos = rayOrigin + rayDirection * dist;
vec3 normal = calcNormal(pos);
float t = length(normal * sin(normal) + normal * cos(normal));
t = length(normal * sin(normal));
vec3 a = vec3(0.2, 0.2, 0.8);
vec3 b = vec3(0.4, 0.1, 0.8);
vec3 c = vec3(4.0);
vec3 d = vec3(0.1, 0.2, 0.3);
vec3 albedo = palette(t, a, b, c, d);
float sonnarDeapth = fract(10.0 * iTime * 0.025) * 40.0 ;
float sonnarWidth = 0.5;
float sonnarFactor = smoothstep(sonnarDeapth - sonnarWidth, sonnarDeapth, dist) * (1.0 - smoothstep(sonnarDeapth, sonnarDeapth + sonnarWidth, dist));
//albedo = mix(albedo, SONNAR_COL, sonnarFactor);
vec3 diffuseLightCol = getLight(pos, lightPos, normal);
//dist negative for to far fields
vec3 background = mix(albedo * diffuseLightCol, vec3(1, 0, 1), step(dist, 0.));
background = mix(background, SONNAR_COL, sonnarFactor);
vec3 finalCol = background;
//return background;
//return vec3(dist);
vec3 fogCol = mix(FOG_COL, SONNAR_COL * 0.01, step(sonnarDeapth - 1.0 - dist, 0.0));
return applyFog(background, dist, rayDirection, normalize(lightPos), fogCol);
}
void main()
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = (sv - 0.5) * iResolution.xy / iResolution.y;
// Time varying pixel color
vec3 col = render(uv);
//col = vec3(iMouse.x, iMouse.y, 0.0);
//Gama correction
col = pow( col, vec3(0.4545));
// Output to screen
gl_FragColor = vec4(col ,1.0);
}