Skip to content

Instantly share code, notes, and snippets.

@justinmeiners
Created January 12, 2022 20:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justinmeiners/0b7a2dbd6ff32ca72416fdbdcef2f4c9 to your computer and use it in GitHub Desktop.
Save justinmeiners/0b7a2dbd6ff32ca72416fdbdcef2f4c9 to your computer and use it in GitHub Desktop.
float g_epsilon = 0.002;
float g_max = 50.0;
float sdSphere( vec3 toCenter, float s )
{
return length(toCenter)-s;
}
float sdBox( vec3 p, vec3 b )
{
vec3 q = abs(p) - b;
return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0);
}
float sdPlane(vec3 p, vec3 n)
{
return dot(n, p);
}
vec2 worldDistance(vec3 p)
{
vec3 sphereCenter = vec3(2.0, 0.0, 0.0);
float dist1 = sdSphere(p - sphereCenter, 1.0);
float dist2 = sdBox(p, vec3(1.0, 1.0, 1.0));
float dist3 = sdPlane(p - vec3(0.0, -2.0, 0.0), vec3(0.0, 1.0, 0.0));
if ((dist1 < dist2) && (dist1 < dist3))
{
return vec2(dist1, 0.0);
}
else if (dist2 < dist3)
{
return vec2(dist2, 1.0);
}
else
{
return vec2(dist3, 2.0);
}
}
vec3 worldColor(vec3 p, int id)
{
switch (id)
{
case 0:
return vec3(1.0, 0.0, 0.0);
case 1:
return vec3(0.0, 0.0, 1.0);
case 2:
return vec3(
(mod(p.x, 1.0) - 0.5) * (mod(p.z, 1.0) - 0.5) > 0.0,
1.0,
1.0
);
}
return vec3(0.0, 0.0, 0.0);
}
vec3 worldNormal(vec3 p, int id)
{
switch (id)
{
case 0:
return normalize(p - vec3(2.0, 0.0, 0.0));
case 1:
if ((abs(p.x) > abs(p.y)) && (abs(p.x) > abs(p.z)))
{
return normalize(vec3(p.x, 0.0, 0.0));
}
else if (abs(p.y) > abs(p.z))
{
return normalize(vec3(0.0, p.y, 0.0));
}
else
{
return normalize(vec3(0.0, 0.0, p.z));
}
break;
case 2:
return vec3(0.0, 1.0, 0.0);
}
return vec3(0.0, 1.0, 0.0);
}
vec4 raytrace(vec3 ro, vec3 rd)
{
vec4 color = vec4(0.4 * rd.x, 0.4 * (rd.x + 1.0) / 2.0, 1.0, 1.0);
float t = 0.0;
const int maxSteps = 60;
for(int i = 0; i < maxSteps; ++i)
{
vec3 p = ro + rd * t;
vec2 hitInfo = worldDistance(p);
float d = hitInfo.x;
if (d < g_epsilon)
{
vec3 n = worldNormal(p, int(hitInfo.y));
vec3 l = normalize(vec3(1.0, 1.0, 0.0));
vec3 base = worldColor(p, int(hitInfo.y));
color = vec4(max(dot(n, l), 0.2) * base, 1.0);
break;
}
else if (d > g_max)
{
color = vec4(0.0, float(i) / 32.0, 0.0, 1.0);
break;
}
t += d;
}
return color;
}
mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = (fragCoord.xy / iResolution.xy) * 2.0 - 1.0;
uv.x *= iResolution.x/iResolution.y;
float time = 15.0 + iTime;
vec3 ro = vec3( -0.8+3.5*cos(0.5*time), 3.0, 0.8 + 3.5*sin(0.5*time) );
vec3 ta = vec3( 0.0, -0.4, 0.0 );
// camera-to-world transformation
mat3 ca = setCamera( ro, ta, 0.0 );
// ray direction
vec3 rd = ca * normalize( vec3(uv.xy,2.0) );
fragColor = raytrace(ro, rd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment