Loop artifacts on GeForce6


I am trying to do a single pass raycasting for volume rendering on a GeForce6800. At the moment, I get the startposition and endposition of the ray from frontface and backface images of the boundary geometry.

For calculating the final result of raycasting I need two loops in a fragment shader:

while( t <  tEnd  && NoEarlyRayTermination) 
     int j = 0;     
     while(j < 32 && t < tEnd)     
          //Look at volume texture, do some shading and compositing          
          t += samplingDistance; 
          ++ j;      

//t = ray parameter
//tEnd = end of ray
//samplingDistance = some value like 0.0025

My problem is the strange behavior of this shader. If I try it out with a sparse sample volume of some blood-vessels (volume size: 416x512x112) there are some artifacts which look like multicolored quads. Look at the following image to see the artifacts:
raycaster loop artifacts

At first I thought I hit the instruction limit. However, I did some tests and it must be another issue: First of all, the artifacts depend on the size of the viewport. When I am close to the volume I see less artifacts, when I am further away from the volume, the artifacts appear more often.

Second: The bounding geometry I use encloses the volume quite well. Therefore the number of iterations is already limited. In fact, I visualized the number of iterations and I got about 220 iterations at most for this volume. This means the shader executes at most about 20000 instructions which is still pretty far from the 65k instruction limit of the Geforce6.
Also, when using just a single loop, the artifacts disappear, but this is not an option since most volumes have higher resolutions.

Is there any explanation for this problem? Does someone have similar problems?

Any hints are welcome

There is one good approach for every problem with shaders: strip down the shader to minimum and start adding all features step by step.

I guess your starting point would be displaying difference between ray start and end position.
Then you can add loops and display loop iteration count, and so on.

A little performance hint by the way:

int j = 0;
while(j < 32 && t < tEnd)

Replace this with:

int j = min(32, (tEnd - t) / tStep);
while (j > 0)

Loops and conditionals are very expensive.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.