   volume rendering, empty space leaping
  Hello there,I have a problem and need some help from you. I have implementedraycasting for volume rendering. Now I'm implementing empty space leapingto skip areas of the volume that not contribute to the final image.Therefor I create a octree like texture and sample the volume data oncpu side and get the min and max value of each area. Let's assume I havea volume file loaded that is 256x256x256 and I my octree like structureis 16x16x16. So each cell's dimension is 16 in every direction. Each cellcontains the min and max value from the original volume data. Furthermore I created a min/max field that contains combinations of min/max pairs. It's justa simple 2d array with length 256 and width 256.The octree like structure and the min max array are uploaded to the gpu as uniformparameters in my shader.The octree texture is a sampler3D and the minmax array isa sampler2D.Without emptyspace leaping, every ray runs through the volume and composed thecolors. With empty space leaping I want to skip empty areas.First, here is some shader coderay aabb intersectionfloat rayaabb(vec3 samplePos, vec3 raydir){  vec3 cellMin = floor(samplePos/ cellSize) * cellSize;  vec3 cellMax = cellMin + vec3(cellSize);  vec3 tmin = (cellMin - samplePos)/raydir;  vec3 tmax = (cellMax - samplePos)/raydir;  vec3 rmin = min(tmin, tmax);  vec3 rmax = max(tmin, tmax);  return min(min(rmax.x, rmax.y), rmax.z);}raycasting shaderfloat t= 0.0;float tIncr = 0.0;float steps  = 0.0;float tEnd  = 1.0;vec3 cellMin,cellMax,rayDir, rayIncr;vec4 result = vec4(0.0,0.0,0.0,0.0);    raySetup(first, last, rayDir, rayIncr, tIncr, tEnd);vec3 samplePos = first;for(int i = 0; i <= samplings; i++){  float visible = texture(texMinMax, texture(texOctree, samplePos).rg).r;  if(visible > 0)  {   // get voxel   vec4 voxel;   voxel.a = getVoxel(texVolume, samplePos).a;   // apply transfer function   vec4 color = texture(texTransfer1d, voxel.a);   voxel.xyz = calcGradientCd(samplePos, t, rayDir, texcoord);   // apply shading   color.rgb = phongShading(voxel.xyz, samplePos, color.rgb, color.rgb, vec3(1.0, 1.0, 1.0)) ;   // compose   color.a = 1.0 - pow(1.0 - color.a, opacityFactor);result.rgb = result.rgb + (1.0 - result.a) * color.a * color.rgb;   result.a = result.a + (1.0 -result.a) * color.a; t += tIncr;   }   else   {cellMin = floor(samplePos / cellSize) * cellSize;cellMax = cellMin + vec3(cellSize);float distance = rayaabb(samplePos, rayDir);t = t + tIncr * (distance / tIncr);   }   samplePos = r0 + t * rayDir;   if(result.a >= 0.95) { result.a = 1.0; break; }   if(t >= tEnd) { break; }}First, I setup the ray with start position. In this raycasting the ray never starts outside the volume. Because the entrypoints are generated from a color coded cube with colors from 0,0,0 to 1,1,1. So the ray can never start outside.The first step in the main loop is a look up to decide wether the area at the current sample position is empty. texOctree contains the 16x16x16 cells generated on cpu side. It's a RGB texture that holds the min and max for this cell. Min and max can be from 0 up to 255 (voluem data is 8bit). With the min max value I look up in the min max texture to get a value that indicates this cell is visible or not. When changing the transfer function I only update the minmax texture.When data is visible I render as usual => get color from 1d transfer functionand apply shading. If it's not visible I calculate the current cell the ray is in.cellMin = floor(samplePos / cellSize) * cellSize;cellMax = cellMin + vec3(cellSize)cellSize is 1/octree dim. That means, here the cellSize is 1/16, because my octree cell is 16x16x16.With the current cell the ray is in, I calculate the intersection point with thecurrent rayposition (samplePos) and the above calculated cell. Therefor I usethe rayaabb function. It's based on a slab test. Because the ray position isalways in a cell or on a cell edge I only need tmax from this intersection function. Dividing this distance by the sample length (tIncr) I get the amount of samplesI can skip.In theory it works ;) but pracitcally it doesnt work correct. It seems that sometimes tmax is wether 0 or too large. Then I see just nothing. It only "works" when I move the camera to a certain position. If I move the camera further the object starts disappearing and the framerate drops down.Here are some picturesThe first two picture show the movement to the certain camera position wheremy empty space leaping "works"This is the camera origin point of view. position is 0,0,5 and view vector is 0,0,-1.At this picture I reached that point. The object is visibleThis picture shows the same object but I changed the transfer functionThis last picture show, when I move the object. You can see that it startsdisappearing. At this point the framerate also drops down massivley.The dropdown of the framerate makes me think that the calculated distance is too short, because the ray is wether terminated when accumulated alpha values are near to 1.0 or when the t is greater than tEnd. tEnd is the maximal length a ray can traverse the volume til it leaves it.I dont know else what to do. I checked the intersection function on cpu side with some values and it seems to work properly. I mean, actually it souldnt be so difficult. Check if the area is visible or not. Calculate new t and advance the ray.I really hope there is someone who can help me out.regards,c-mosEdit: In general, this empty space leaping works. When I set the skip distance to a fixed value, for instance 10, than visible parts are rendered with normal sampling wide and non visible areas are skipped with 10times the sampling wide.[Edited by - c-mos on September 2, 2010 6:03:49 AM]