microsoft / DirectX-Graphics-Samples

This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows.
MIT License
6.04k stars 2.03k forks source link

Ray traced 'holes' appearing on procedural geometry edges #550

Closed digbeta closed 5 years ago

digbeta commented 5 years ago

I have been working with the Ray Tracing procedural geometry example and recently found an issue I am unable to diagnose. I have created a new procedural shape: (sdTorus(p, h) + 0.045sin(20.0p.x)sin(20.0p.y)sin(20.0p.z)). This gives the shape below:

shape-holes

I was evaluating the resolution independence of images produced using this method and when viewing the shape very closely I found that often times you can see transparent holes in the geometry that I can't explain. I'm not certain, but these holes seem more prominent when the shape surface is concave. See the marked bounding boxes in the images below showing how the rays are tracing through geometry and don't seem to be rendering a hit.

holes1

Note in the picture above and below you can see the green of the object behind the yellow shape along with either the ground or background.

hole2

holes4

I thought maybe this was noise related, but this only seems to be happening on edges. Also, I think this is also present on the demo shapes, see the images below. First image is a perspective through the intersected round cube:

squarehole

and the gear shape (see below):

gear

Any help is appreciated.

pkristof commented 5 years ago

Hi, This is likely due to the nature of the SDF sphere tracer (implemented in RaySignedDistancePrimitiveTest(...)). The sphere tracer adjusts its iteration step based on the SDF/distance to a geometry. For rays grazing the surface it can get to close distances, and thus use smaller iteration steps, eventually running out of the allowed number of steps "MaxSteps" before crossing the surface boundary and, thus, returning a NoHit result for the object's AABB. You can increase stepScale variable defined per object for object this impacts. The variable scales the ray marching steps taken. You can also try increasing "threshold" (in RaySignedDistancePrimitiveTest()) to accept surface hits sooner, at the cost of more false positives.

digbeta commented 5 years ago

Peter,

Thanks so much for your quick reply. I can confirm your suggested fix works. I wasn't as familiar with that portion of the example code, so thanks for pointing that out.

Thank you again!

-Eric