Optomizing Ray Tracing
#1
Posted 12 September 2005 - 04:56 PM
Do any ray tracing geeks here have some suggestions on how I can speed up this portion of the code? I am only interested in knowing if a ray intersects another triangle at all and I do not care if the hit is the closest one like a normal ray tracer would want.
Currently I am using a KD tree to store the triangles and I test against that. Perhaps someone knows of some good ways to choose the location of the splitting plane when constructing the tree so as to speed up traversal and minimize double tests?
#2
Posted 13 September 2005 - 06:27 AM
It also really helps to indentify leaf nodes that share exactly the same triangles, which happens really a lot. This is a preprocessing step though, since it can take up quite a bit of time for larger triangle meshes.
#3
Posted 13 September 2005 - 01:18 PM
So basically what you do is instead of having a simple bounding box structure, you have some extra information in that structure. Like with frustum culling you have to check all six sides before an object can get accepted right. So if I'm using bounding spheres for instance, my structure is this:
struct {
float radius;
vector position;
int frustumIndex;
};
Then whenever you test the sphere against the frustum, you record which plane it failed against. So the next time you do the test, you start testing from frustumIndex'th plane instead of from plane 0. So instead you doing 6 tests and having the sphere rejected on the sixth test, you'll probably have one test instead.
so:
int count = 0;
int idx = boundingBox.frustumIndex;
while( count++ < NumFrustumPlanes )
{
if( ObjectIsInPositiveHalfSpace( boundingBox, FrustumPlane[idx] )
{
boundingBox.frustumIndex = idx;
return OBJECT_OUTSIDE
}
idx++;
}
Anyway, I'm just shooting in the dark right now, had a very long day so if what I've said is jibberish then I appologize.
- Me blog
#4
Posted 13 September 2005 - 01:36 PM
One thing that did occur to me as I was reading your post though, is that it is often the case that a few triangles completely obscure one vertex. Perhaps if I keep a list for the current vertex of each triangle that a ray has hit, I can those few first before I go into the tree. This would only help me in the cases where triangles occlude large portions of the visible area from the vertex and also only if my ray test hits that particular triangle and not some smaller triangle further away that just happened to also be in the path of the ray.
#5
Posted 13 September 2005 - 01:50 PM
#6
Posted 13 September 2005 - 03:14 PM
#7
Posted 13 September 2005 - 03:26 PM
NomadRock said:
Cheers, Altair
#8
Posted 15 September 2005 - 08:43 PM
Altair, do you mean modifying the collision routines to check colissions with several rays of different origins at once? and how would this map to the GPU? The only decent ways I have seen to handle it on the GPU is to handle just one vertex at a time and check it's accessibility in the vertex shader.
#9
Posted 15 September 2005 - 10:07 PM
NomadRock said:
Btw, AO usually has some range for the ray and attenuation so you would need to modify the algorithm to support that.
Cheers, Altair
#10
Posted 18 September 2005 - 05:52 AM
The scene consists of a single very large and very complex model like a tractor modeled down to every last detail. I've read some papers dealing with alternate shapes for the nodes in a tree, but they seem to be geared toward closely following the outside of a roughly convex object, and I only have one object that needs to be split a bunch of times...
Anyone have any experience with this or any suggestions? Oh, and altair, i've already considered using the rendering approach, but this approach does not require the use of a graphics card so it can be run (hopefully) efficiently on headless clusters. These boxes may not even have graphics cards much less 3d accelerated cards.
#11
Posted 19 September 2005 - 12:55 PM
NomadRock said:
Cheers, Altair
#12
Posted 19 September 2005 - 02:39 PM
As for using the graphics card, i've found a vertex/fragment shader implementation of AO by nvidia that I am going to use before I work out these other algorithms.
At this point I am really just looking for a way to build the KD tree so as to minimize the tri/ray tests that miss.
#13
Posted 19 September 2005 - 02:54 PM
NomadRock said:
As for using the graphics card, i've found a vertex/fragment shader implementation of AO by nvidia that I am going to use before I work out these other algorithms.
At this point I am really just looking for a way to build the KD tree so as to minimize the tri/ray tests that miss.
Cheers, Altair
#14
Posted 19 September 2005 - 06:32 PM
This is indeed possible but requires enormous amounts of buffer space. I am dealing with models that have millions of triangles, even if each buffer is only one byte that means we are working with a megabyte of information. if we work on a very smal resolution of 256x256 pixels optomized to store only 4 bytes for the depth and assume a certain depth implies a miss, then we are well over 200GB of memory needed...
If plan on using only one buffer for each direction, then you loose information about triangles that have been occluded and cannot know the depth of those for rays that start further in than the front triangle.
#15
Posted 19 September 2005 - 06:56 PM
NomadRock said:
Okay, let me try to put it in different way: What I'm proposing is just the basic simple shadow mapping algorithm, but you run the algorithm 100 times (for lights from 100 directions), so you need a single shadow buffer (e.g. 256x256).
NomadRock said:
Cheers, Altair
#16
Posted 19 September 2005 - 11:21 PM
#17
Posted 20 September 2005 - 03:18 AM
NomadRock said:
Cheers, Altair
#18
Posted 20 September 2005 - 03:59 AM
Keep in mind that if my model is the surface waves on an ocean, and the rays in question go parallel to the water surface, then we have many waves overlapping each other from that view. Rays with an origin above the highest peak or below the lowest trough will be trivially rejected. Rays between the peaks and troughs will be a trivial hit as long as the origin is within the accepted distance of the first wave, but rays with an origin past the first wave will not be able to tell how far it is to the next wave with just 32 bits at that pixel. It is possible to just keep track of the furthest points and this would work if we didn't care about distance to the intersection point and just that it eventually hits some wave.
We have already decided to care about rejecting rays that while do intersect the geometry at some point do not within a reasonable distance. This provides a bit better looking results while reducing the search space within the KD tree.
This is something to keep in mind if we decide to go back to not caring about the distance. Currently the KD tree uses about 4MB of memory on a million triangle mesh. In order to preserve decent detail I doubt 256x256 would be enough resolution for any ray on the model but assuming it is we are working with 100 directions * 4 bytes * 256x256 = 25MB, at 512 it is 100MB and 400MB at 1024 which while quite large is still managable on a workstation, and 100 frames would render in a second or so.
We loose the ability to test ray length, but this could be a useable option for quick tests.
Do I understand you now?
#19
Posted 20 September 2005 - 12:57 PM
NomadRock said:
Cheers, Altair
#20
Posted 20 September 2005 - 02:10 PM
True, the multiple buffer thing was my oversight, as long as you took the time to iterate through all the objects for each direction you could rasterize once per iteration and reuse the buffer. Interestingly enough, this would also allow for arbitrarily precice calculations (assuming perfect renders) because you could just let the thing calculate for as many ray directions as you have time.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












