Distance Field Camera Clipping Issue (Julia Demo)


I’ve been developing a 3D Fractal renderer using Optix, based off of the Julia demo’s method of calculating distance field intersections (find intersection with a sphere and then raymarch from the hit point, if any). I’ve noticed that if I go too close (or inside) an object raymarched with the same technique, I get camera clipping issues.


This also seems to occur even in the original Julia demo:

Does anyone have any idea why this is happening? The fact that it’s in the original demo worries me.

Any help would be greatly appreciated!

“find intersection with a sphere and then raymarch from the hit point, if any”

Looks like the case when starting with ray.origin inside the sphere (no initial hit point) is not arriving at the same ray marching parameters as when starting outside the sphere.
I would recommend to analyze that special case by adding some rtPrintf calls which dump the applied parameters in a single launch index where you can dynamically make the geometry appear and disappear.

Example code I use to enable debugging a single launch index (in the center of a 512 * 512 launch size).

    // Disable this by default for performance, otherwise the stitched PTX code will have lots of exception handling inside. 
    m_context->setPrintLaunchIndex(256, 256); // Launch index (0,0) at lower left.
    m_context->setExceptionEnabled(RT_EXCEPTION_ALL, true);

Also make sure you have an exception program set which prints the exception code in case this is an invalid ray or stack exception.

rtDeclareVariable(uint2, launchIndex, rtLaunchIndex, );

RT_PROGRAM void exception()
  const unsigned int code = rtGetExceptionCode();
  rtPrintf("Exception code 0x%X at (%d, %d)\n", code, launchIndex.x, launchIndex.y);

Thanks for the helpful reply! I admit I forget I can use printf in heavily parallel code like this, but it helped narrow down the issue. I replaced the single intersectBoundingSphere check with something like

float distance;
if( insideSphere(ray.origin, make_float3(0,0,0), sqRadius, &distance) )
//      rtPrintf("Inside sphere : %f\n", distance);
      tmin = 0;
      tmax = RT_DEFAULT_MAX;
      shouldSphereTrace = true;
//      rtPrintf("Outside sphere : %f\n", distance);
      // Push hit to nearest point on sphere
      if( intersectBoundingSphere(ray.origin, ray.direction, sqRadius, tmin, tmax) )
          shouldSphereTrace = true;

I’m not sure if it’s the best way of doing it, but it seems to work fine for the most part. It also fixed an issue I had with shadow rays not properly colliding, presumably because of the same issue.

Thanks for helping me fix this.