I'm "raymarching distance fields" (proper lingo: sphere-tracing) in GLSL. To implement cone-marching atop of it (and also to minimize the number of raymarching steps regardless of whether cone-marching is added or not), I need to estimate the radius of the ray cone at any given distance.

Recall with raymarching distance fields, a "hit" is recorded when the distance to an object is smaller than a threshold value, often in code named nearLimit or epsilon. This threshold can be seen as equivalent to the ray-cone radius if we increase it exponentially with distance traveled -- this way, we don't shoot straight thin ray lines into space but cones expanding in accordance with perspective projection. This more accurately covers catching the "right" distant objects (at this point let's ignore the issue of blending materials and filtering normals of all intersected objects in the viewing cone at distance t for now...).

At step 0, this radius can be approximated by something such as

float fInitialRadius = 1 / min(screenwidth, screenheight);

This can then be increased at each step exponentially by applying the starting radius to the distance:

fNearLimit = fTotalDist * fInitialRadius;  // after each raymarching step

This works OK but still has artifacts. If I use fInitialRadius*fInitialRadius (resulting in a smaller number since initial radius for a 640px framebuffer and a unit-width view-plane is 1/640) I get less artifacts and a more accurate result. But both approaches are inaccurate, the first is too eager (increases radius too much too early), the latter too lazy (increases radius too little too late).

The most accurate factor to increase fNearLimit / the cone radius at a given distance must most likely take into account my current field of view and will vary depending on whether field-of-view is 45° or 60° or 90° or...

TL;DR: I want to know what's the proper calculation or most acceptable approximation of the cone radius at a given distance given the initial pixel radius at step 0 and the field of view angle?


1 Answer 1


If I understand your question correctly, the calculation you're trying to do is very similar to the standard projection or primary-ray generation calculations. Here's a rough diagram that illustrates the solution.

  • \$\begingroup\$ Yeah it also later occurred to me that "simply the normal projection logic" should be applied here. Still I wasn't sure if I should do pixelWidth * distance * tan(fov/2) -- or pw * d * (1 / tan(fov/2))) -- from your doodles seems like it's the former. Thanks! Right now it's hard to "test visually" as I get aliasing artifacts in the distance either way. \$\endgroup\$
    – voxelizr
    May 11, 2012 at 5:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .