How does optix code compilation work?

What I’m doing now is like the last picture you showed. If I choose the curves’ thickness less than 3e-4, I got wrong results, some rays miss when they are supposed to hit. Could this happen with the underlying algorithm in Optix?

How did you get the picture in the middle? Did you use 2 triangles to make up the squares? If I later decide to go this way, is there a nvidia’s library to do triangulation of polygons?

Yes curves have precision limits. This is true for triangles too, it’s best to avoid extremely skinny triangles as well. The curve precision depends on the ratio of the curve length to the curve radius. It can also depend on the distance from the ray origin to the curve. How long are your curves with radius 3e-4 – what is a typical distance between control points? Extreme cases of very thin and very long curves have a high ratio of length to radius, so they can end up hitting the precision limits. I believe you could improve the precision by sampling each of your curves into multiple smaller curves. For example, replace each segment with 10 or 100 linearly interpolated segments that have a lower length/radius ratio.

If you feel like the curve length & thickness should be reasonable, one thing you could do is post the ray origin & direction, and the two control points and radius of the curve and I can look into whether I see the same precision issues.

Are you using a very thin radius in order to get sharp corners, or to avoid having to offset the curves by their thickness? If so, the curves might be better represented using triangles in OptiX, like the middle picture above. Yes I tessellated this box manually and used 2 triangles for each quad. I don’t know of a library that can help you generate triangles, but it should be fairly straightforward and simple I think.


David.

my mistake, not 3e-4, but 4e-5.

as a test, i tried 2 squares, the first (-0.75, -0.75) bottom left and (-0.25, -0.25) top right, and the second (0.25, 0.25) bottom left and (0.75, 0.75) top right. my observer is at (0, 0) and i shot 360 rays at every degree angle. when thickness = 3e-5, some rays went through the squares. at 4e-5 thickness, they looked correct.

yes, i want sharp corners. my real case polygons can have millions (usually zigzag) edges of various lengths. i dont want the triangle tessellation to be the bottle neck so i would prefer an algorithm parallelizable on gpus. any reference?

Ah yes this radius is pushing the curve to near the limits of floating point precision. Notice that this is the same as intersecting a curve with radius 1 that is 100,000 units long and 100,000 units away from the camera. I can reproduce the issue you’re seeing, and it does help to subdivide the curve segments, even into 2 curves each, but a subdivision of 3 or 4 or 10 is better. I don’t think there’s a very meaningful difference between 3e-5 and 4e-5, I don’t see 0 misses until the radius is 7e-5 (which is only 1 extra bit of precision).

Subdividing may be the easiest thing to do to improve this, but you might want to use triangles instead, I think triangles is a safer choice in the long run. (Plus it will be faster to trace and lower memory than subdividing). Are you generating the curve data in a CUDA kernel currently? Tessellating should be quite straightforward and is definitely parallelizable on the GPU. You need to create a vertex buffer. Since you’ll want to extrude the edges, you need one copy of the points above Z=0, and one copy below Z=0. So if you have all the 2d data, just make two copies back-to-back in a buffer and set the Z values to, say, +/- 1. Then you need an index buffer, and you can create this in CUDA kernel using the polygon connectivity information you have. If you have a list of edges, then generating the index buffer is pretty trivial. If you only have a list of polygons, you might need to generate a prefix-sum table of the polygon lengths in order to parallelize the index buffer creation. If each thread in a CUDA kernel is responsible for outputting the indices for 1 of your 2d polygons, you’ll need to have the offsets of where to start looking in the input vertex buffer, where to start outputting indices into the output index buffer, and what your starting index value should be. If all your polygons are similar size (# of edges) then it will parallelize nicely. If you have any extremely large polygons then you might want to be more careful or use edge indexing per thread instead. The Nvidia Thrust library is good for doing things like kernel reductions or prefix sum computations, that can come in handy here if you end up needing something non-trivial.


David.

thank you for your response. i’ll have to see if my subsequent computation can tolerate the thickness precision and think more on the approach with triangles. i’ll come be with more questions.

1 Like