// Mandelbox distance function float map(vec3 pos) { vec4 p = vec4(pos,1); vec4 p0 = p; for (int i = 0; i < 20; i++) { p.xyz = clamp(p.xyz, -1., 1.) * 2. - p.xyz; float r2 = dot(p.xyz, p.xyz); p *= clamp(max(.25 / r2, .25), 0., 1.); p = p * (vec4(2.8, 2.8, 2.8, abs(2.8)) / .25) + p0; } return (length(p.xyz) - 1.) / p.w - pow(abs(2.8), -9.); } vec3 n(vec3 p) { vec2 e = vec2(.001, 0); return normalize(vec3( map(p - e.xyy) - map(p + e.xyy), map(p - e.yxy) - map(p + e.yxy), map(p - e.yyx) - map(p + e.yyx) )); } // Ray marcher void mainImage(out vec4 o,vec2 c){ // Adjust coordinates system vec2 uv = c / iResolution.xx - iResolution.xy / iResolution.xx / 2.; vec3 rd = normalize(vec3(uv, 1.)); // Starting point for the ray (eye position) vec3 p = vec3(iCam.x, iCam.y, -10. + iCam.z); // Iterations const float it = 999.; // Default color (black) vec3 col = vec3(0.); // Iterate for each pixel for (float i = .0; i < it; i++){ // Compute remaining distance from ray to Mandelbox float dist = map(p); // Choose a distance where the ray is close enough if (dist < .001){ // Set color according to the number of iterations col = vec3(dot(n(p), vec3(0,0,1))); // Stop break; } // If ray is not close enough: advance the ray according to the remaining distance p += rd * dist; if (p.z > 5.) break; } // Color the pixel o.rgb = col; }