One of the features of ray marching is that you can use modulus to repeat shapes infinitely, like in the image below, which is from https://www.shadertoy.com/view/MsBGW1

enter image description here

I was curious if there exists any technique which allows you to do the same thing with ray tracing instead of ray marching?

One method I do know of is to ray trace a plane from above, and then where you hit the plane, calculate your location on a grid on that plane, and use the relative position in that grid cell as an absolute position to raytrace a scene. That will repeat the scene across the grid.

However, a problem with that is if your ray doesn't hit anything in the grid cell, and it would then enter another grid cell, this technique won't catch those other shapes without walking the grid cells down the path of the ray until it exits the back side of the grid, which is very ray-marching-esque and iterative.

Does anyone know of a technique that allows you to have ray marching type repetition in ray tracing?


2 Answers 2


I've tried to figure this out as well, but I don't think there is a solution that is just as performant as tracing one sphere. Basically you would want to cast one ray to hit a infinite set of repeating spheres with no marching iteration. That would be awesome but is not possible: Let me explain.

Ray-tracing is basically finding the analytical solution to this equation: $$ f(\vec{r(t)}) = 0 \ for \ t $$

Where $f(\vec{p})$ is the implicit surface function (which gives the distance the given point $\vec{p}$ is from the surface) and $\vec{r(t)}$ is the parametric ray equation ($\vec{r(t)} = \vec{origin} + \vec{direction}*t$). $t$ would represent the distance along the ray the intersection happens.

In order to ray-trace domain manipulations (like repeating space), these domain manipulations need to be present in the implicit surface function $f(\vec{p})$ while finding an analytical solution. Let's take a 3D repeating sphere for instance. $$ f'(\vec{p}) = \|\vec{p}\bmod \vec{d}\| - r $$ (where $\vec{d}$ is a constant representing the grid size and $r$ is the radius)

In order to solve $f'(\vec{r(t)}) = 0$ for $t$ we would need the inverse of the modulo operator which doesn't really exist : Link. That means there is no analytical solution to this equation, but there is a numerical one. Hence Ray-marching.

This is true for a lot of cool distance functions you see on shadertoy.com, the analytical solution does not exist for these surfaces so you cannot ray-trace.

  • $\begingroup$ Thanks for the answer! Interestingly, I have had some limited success at this, thanks to some ideas from someone on twitter. I'm experimenting more to come up with some final info & a blog post, and will post an answer here with the details. It's not a general solve, but it is still a bit interesting. Maybe extensible. Also had a friend mention he has been able to do this with other limited success by faking modulus mathematically, like using a badlimited saw wave. I'll share some shadertoy links in the next comment for the curious. $\endgroup$
    – Alan Wolfe
    Oct 26, 2016 at 17:30
  • 1
    $\begingroup$ Shadertoy from sebbi showing his idea: shadertoy.com/view/lly3Rc Me exploring and formalizing some things: shadertoy.com/view/MlK3zt Limited success for ray vs infinite layers of concentric circles: shadertoy.com/view/4tyGDK I'm currently working on ray vs infinitely repeating pillars. Looking promising so far. In the end these things are interesting but not in general very useful. Maybe they can be extended. ::shrug:: $\endgroup$
    – Alan Wolfe
    Oct 26, 2016 at 17:34
  • $\begingroup$ Regarding there needing to be an inverse operation for modulus, there is the form: i = 3N where N is in Z, as a reverse of i%3 = 0. If we had a solution of that form, we could plug in a value for N, presumably 0? $\endgroup$
    – Alan Wolfe
    Oct 26, 2016 at 19:46
  • $\begingroup$ Couldnt you cheat a bit though. You could raycast on a cube and solve which parta of cube edge hits which sphere. $\endgroup$
    – joojaa
    Dec 11, 2019 at 19:09
  • $\begingroup$ @joojaa if you were talking about cubemap stored infintie spheres that could work, but I devised an iterative process that works like light traveling through "portals" (mirrors except change position instead of direction) which gets the exact same image but using the classic recursive raytracing algorithm with imaginary objects. $\endgroup$
    – cmarangu
    Feb 9, 2020 at 4:52

If you want to warp the space as in the raymarching infinite spheres example,

float SDF (vec3 p) {
    p = mod(p+3., 6.)-3.;
    return length(p-vec3(0., 0., 0.))-2.;

what you really need to do is warp the space by turning it into a cyllindrical one and what that means is that you need to make it so that if a ray hits a wall, the wall is like a portal to the wall opposite it and it comes out of the same point on the opposite wall. To do this you could just here is some pseudocode:

Color trace (vec3 p, vec3 d) {
    if (intersects sphere) {
        *return sphere color with recursive tracing blah*
    Plane frontwall = plane(vec3(0, 0, 3), vec3(0, 0, -1));
    Plane backwall = plane(vec3(0, 0, -3), vec3(0, 0, 1));
    Plane leftwall = plane(vec3(-3, 0, 0), vec3(1, 0, 0));
    *find closest wall intersection and then*
    return recursively traced color from opposite wall than the one that got hit

of note is that to do this enough times for it to look infinite, you would need like thousands of recursion iterations which would probably be slow and whatever language would probably not allow it, so your other option is to use some kind of a for loop since each portal/wall-intersection only requires base-1 recursion and therefore can be easily tranformed into an iterative process.

And instead of downvoting, I would request anyone who found my answer unhelpful to elaborate on how I could improve it; if someone really is interested in seeing a proof of concept of this in action then I will provide one but until that seems to be the case I will not waste my time.

  • $\begingroup$ This is true, and worth putting the answer up. The unspoken (sorry, I'll edit) goal is to find something not iterative. $\endgroup$
    – Alan Wolfe
    Dec 2, 2019 at 3:21
  • 1
    $\begingroup$ oh. well in that case it might be worth looking into this thread about some strange connection between the projected cubic lattice, complex numbers, and polynomials twitter.com/stevejtrettel/status/1192827919447547905 $\endgroup$
    – cmarangu
    Dec 3, 2019 at 13:32
  • $\begingroup$ Very interesting! $\endgroup$
    – Alan Wolfe
    Dec 3, 2019 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.