enter image description here

I'm working on a shadertoy "snake" game, using the new multi pass rendering abilities to save game state between frames.

I'm using raytracing to render the board (an AABB), and am planning on using spheres to render sections of the snake's body.

The game board is a 16x16 grid and each grid can either have a sphere there (a segment of the snake's body) or not. Snake body segments don't move, they are just either there on the grid or not. When the snake moves, a new sphere appears in the front and an old sphere disappears from the back.

The problem I'm trying to solve is how to render the snake body spheres.

For instance, a naive approach would be to store a 16x16 grid in pixels specifying whether there was a snake body in that grid cell or not.

I would then do a ray vs sphere check for up to 256 different spheres within my pixel shader, which seems like a no go.

Another method might be to figure out where the ray begins and ends on the game board (when it's between the high and low height values of where the spheres are) and then use something like bressenham line algorithm to go from the start to the end of the line the ray takes on the board, and check only the grid cells that the ray hits.

The problem there is that it requires a dynamic loop.

Maybe a more practical solution would be to make the camera have a nearly top down view and where the ray enters the playable game world, test any sphere in the cell it hits as well as the 8 neighboring cells.

I'm betting there are some much better solutions that I'm not thinking of.

Does anyone know of any interesting techniques or creative solutions?


Edit: here is an older version of this game i made, which was CPU / software rendered, to give an idea of what I'm planning.

enter image description here

  • $\begingroup$ What's the problem with doing a dynamic loop? That seems like the natural way to solve this kind of problem. If the board has a fixed 8x8 size, the longest ray would only pass through 16 squares at most, so it's not a crazy iteration count. And if you restrict the camera angles like you said, so that people can't look straight across the board, you can cut down the longest ray length considerably. $\endgroup$ Jan 14, 2016 at 0:09
  • $\begingroup$ I've been going down that route without having a better solution, so it's nice to hear your support of it, thanks Nathan. $\endgroup$
    – Alan Wolfe
    Jan 14, 2016 at 0:17
  • $\begingroup$ Have you tried using raymarching instead of raytracing? Raytracing is more of a CPU/software rendering oriented algorithm, whereas raymarching with signed distance fields is much more easy to implement on a GPU, IMO. $\endgroup$
    – EvilTak
    Jan 16, 2016 at 6:24
  • $\begingroup$ For sphere and axis aligned box, directly finding the intersection with raytracing is the better way to go. For more complex shapes, sure, ray marching is definitely a nice option. Ray marching exists to get around having to analytically solve line segment vs arbitrary shape. $\endgroup$
    – Alan Wolfe
    Jan 16, 2016 at 6:35

1 Answer 1


why not building a bounding box (or spheres) hierarchy ?

(but for a shadertoy implementation, the lack of dynamic loop length might spoil the gain ).

  • $\begingroup$ Do you see that working well when you have N grid cells, each of which may or may not have a sphere in it that you need to test your ray against? Maybe a bvh would be better when the grid is mostly empty, but have a worse worst case? Hrm.. $\endgroup$
    – Alan Wolfe
    Feb 8, 2016 at 2:40
  • $\begingroup$ I was thinking using it for the (real) sphere set only, after a first cut to the plate "skin", as you said. Note that dynamics loops are not totally an issue as long as they are bounded; you can break/return/continue using an if inside. only the longest length for a given warp will be applied to all of its pixel.s The only issue is the code length, since loops and functions are unrolled. $\endgroup$ Feb 8, 2016 at 3:13

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.