So the most common question I get, of course, is how does this stuff work? It is actually simpler than it might seem.
At a high level it is based on ray tracing, specifically a method known as Signed Distance Field ray marching (SDF ray marching). But that is only part of what is going on.
Vanilla ray marching simply steps along a ray at fixed intervals until it hits something. This is costly with a small step size, and erroneous with a large step size. SDF ray marching computes the distance from the nearest objects, and moves along the ray no more than the smallest distance from any of these objects.
The problem with naive SDF is that every ray at every pixel is considering every object in the scene to be rendered. This becomes insanely expensive if you have many objects in the scene. For example, imagine I have 1920x1080 pixels to render, which amounts to about 2 million rays to cast. Each ray is calculating the distance from 1000 objects, 60 times per second. Lets imagine each ray travels 100 steps on average, and requires 100 instructions to make its calculations. You are looking at 1.2 quadrillion instructions per second, if I did my math right.
The trick I use is aggressively reducing the number of objects each ray considers, using very straightforward, naive cell hashing.
In order to step through cells efficiently, I recommend using a supercover line algorithm, such that each cell is only considered once as the ray travels through it (image credit: http://lifc.univ-fcomte.fr/home/~ededu/projects/bresenham/).
Because VQ uses only one type of uber geometry (rounded boxes with super-ellipsoid-like corners), it can compute exact hits for every single type of primitive only using one set of instructions (from cones to cylinders to spheres to rounded boxes to you name it), eliminating the need for branching in that area. So it narrows it down to geometry that the ray hits exactly.
But it goes further than that. How many objects is a ray likely to miss? As it turns out, you can usually get away with only considering the first 4 to 8 objects and you will rarely get errors. In the illustration above I have just shown 3 objects, but imagine if that box is filled with hundreds of objects. Now, for each ray, I only need to consider the first couple of objects that get hit instead of hundreds of objects for every ray. As I have shown in the past, you can render millions of objects using this method and there is not really any slow down - it tends to run at a pretty constant speed. You can optionally improve performance further through use of the flyweight pattern or templates. If I am using an object that will be repeated many times (for example, a hallway) - I need only store the specifications for this object once, and then instance of it is just a reference with a bit of data like position and orientation.
Boom Boom Boom, let me hear you say wayoh... #gamedev pic.twitter.com/DQYKwGaiLs
— Gavan Woolery (@gavanw) July 31, 2015
What happens when we apply the ripple effect to land instead of water? #gamedev pic.twitter.com/vTnkn0bFZc
— Gavan Woolery (@gavanw) July 20, 2015
Wizard Pool Party!!! Part Deux. #gamedev pic.twitter.com/u11bpIZqmY
— Gavan Woolery (@gavanw) July 27, 2015
First person camera with collision #gamedev pic.twitter.com/xMo6YD1teb
— Gavan Woolery (@gavanw) July 19, 2015
Maybe a bit better than the last #gamedev pic.twitter.com/ivHRD8boOl
— Gavan Woolery (@gavanw) July 15, 2015