How do I initialize the t-variables in “A Fast Voxel Traversal Algorithm for Ray Tracing”?

后端 未结 2 1874
一整个雨季
一整个雨季 2020-12-14 02:15

I am trying to implement the algorithm explained on this paper, used to traverse grid cells in order following a straight line, which is useful for ray tracing:

http

相关标签:
2条回答
  • 2020-12-14 02:55

    Initialization for X-coordinate variables (the same for Y)

      DX = X2 - X1
      tDeltaX = GridCellWidth / DX
      tMaxX = tDeltaX * (1.0 - Frac(X1 / GridCellWidth)) 
      //Frac if fractional part of float, for example, Frac(1.3) = 0.3, Frac(-1.7)=0.3
    

    Example:

      GridCellWidth, Height = 20
      X1 = 5, X2 = 105 
      Y1 = 5, Y2 = 55 
      DX = 100, DY  = 50
      tDeltaX = 0.2, tDeltaY = 0.4 
      tMaxX = 0.2 * (1.0 - 0.25) = 0.15  //ray will meet first vertical line at this param
      tMaxY = 0.4 * (1.0 - 0.25) = 0.3   //ray will meet first horizontal line at this param
    

    We can see that first cell border will be met at parameter t = 0.15

    0 讨论(0)
  • 2020-12-14 03:03

    The one that worked for me in 3D for both positive and negative directions (in CUDA C):

    #define SIGN(x) (x > 0 ? 1 : (x < 0 ? -1 : 0))
    #define FRAC0(x) (x - floorf(x))
    #define FRAC1(x) (1 - x + floorf(x))
    
    float tMaxX, tMaxY, tMaxZ, tDeltaX, tDeltaY, tDeltaZ;
    int3 voxel;
    
    float x1, y1, z1; // start point   
    float x2, y2, z2; // end point   
    
    dx = SIGN(x2 - x1);
    if (dx != 0) tDeltaX = fmin(dx / (x2 - x1), 10000000.0f); else tDeltaX = 10000000.0f;
    if (dx > 0) tMaxX = tDeltaX * FRAC1(x1); else tMaxX = tDeltaX * FRAC0(x1);
    voxel.x = (int) x1;
    
    int dy = SIGN(y2 - y1);
    if (dy != 0) tDeltaY = fmin(dy / (y2 - y1), 10000000.0f); else tDeltaY = 10000000.0f;
    if (dy > 0) tMaxY = tDeltaY * FRAC1(y1); else tMaxY = tDeltaY * FRAC0(y1);
    voxel.y = (int) y1;
    
    int dz = SIGN(z2 - z1);
    if (dz != 0) tDeltaZ = fmin(dz / (z2 - z1), 10000000.0f); else tDeltaZ = 10000000.0f;
    if (dz > 0) tMaxZ = tDeltaZ * FRAC1(z1); else tMaxZ = tDeltaZ * FRAC0(z1);
    voxel.z = (int) z1;
    
    while (true) {
        if (tMaxX < tMaxY) {
            if (tMaxX < tMaxZ) {
                voxel.x += dx;
                tMaxX += tDeltaX;
            } else {
                voxel.z += dz;
                tMaxZ += tDeltaZ;
            }
        } else {
            if (tMaxY < tMaxZ) {
                voxel.y += dy;
                tMaxY += tDeltaY;
            } else {
                voxel.z += dz;
                tMaxZ += tDeltaZ;
            }
        }
        if (tMaxX > 1 && tMaxY > 1 && tMaxZ > 1) break;
        // process voxel here
    }
    

    Note, grid cell's width/height/depth are all equal to 1 in my case, but you can easily modify it for your needs.

    0 讨论(0)
提交回复
热议问题