Skip to content

Instantly share code, notes, and snippets.

@pohy
Created October 5, 2019 23:27
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 pohy/16c536a05b135a26822c9e8311bc852f to your computer and use it in GitHub Desktop.
Save pohy/16c536a05b135a26822c9e8311bc852f to your computer and use it in GitHub Desktop.
#define MAX_STEPS 100
#define MAX_DISTANCE 100.
#define MIN_DISTANCE .01
float getDistance(vec3 point) {
vec4 sphere = vec4(0, 1, 6, 1);
float sphereDistance = length(point - sphere.xyz) - sphere.w;
float planeDistance = point.y;
return min(sphereDistance, planeDistance);
}
float rayMarch(vec3 rayOrigin, vec3 rayDirection) {
float rayDistance = 0.;
for (int i = 0; i < MAX_STEPS; i++) {
vec3 marchLocation = rayOrigin + rayDistance * rayDirection;
float surfaceDistance = getDistance(marchLocation);
rayDistance += surfaceDistance;
if (surfaceDistance < MIN_DISTANCE || rayDistance > MAX_DISTANCE) {
break;
}
}
return rayDistance;
}
vec3 getNormal(vec3 point) {
float distance = getDistance(point);
vec2 sampleSurface = vec2(.01, 0);
vec3 normal = distance - vec3(
getDistance(point - sampleSurface.xyy),
getDistance(point - sampleSurface.yxy),
getDistance(point - sampleSurface.yyx)
);
return normalize(normal);
}
float getLight(vec3 point) {
vec3 lightPosition = vec3(0, 5, 6);
lightPosition.xz += vec2(sin(iTime), cos(iTime)) * 5.;
//lightPosition.y += abs(sin(iTime)) * 9.;
vec3 light = normalize(lightPosition - point);
vec3 normal = getNormal(point);
float diffuse = clamp(dot(normal, light), 0., 1.);
float lightDistance = rayMarch(point + normal + MIN_DISTANCE * 2., light);
if (lightDistance < length(lightPosition - point)) {
diffuse *= .1;
}
return diffuse;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = (fragCoord - .5 * iResolution.xy) / iResolution.y;
// vec3 col = 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));
vec3 col = vec3(0);
vec3 rayOrigin = vec3(0, 1, 0);
vec3 rayDirection = normalize(vec3(uv.x, uv.y, 1));
float distance = rayMarch(rayOrigin, rayDirection);
vec3 point = rayOrigin + rayDirection * distance;
float diffuse = getLight(point);
col = vec3(diffuse);
//col = getNormal(point);
//col = vec3(distance / 6.);
// Output to screen
fragColor = vec4(col,1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment