
Boost your raytracer
June 5, 2008You can speed up a bit (6-10% maybe) your current raytracer by changing simple linear pixel rendering order into hilbert curve (in that case data are more coherent and there are less cache misses). I did not believe that until I try it.

Here is my Hilbert curve class (drop me a line if you find it usefull):
#ifndef HILBERT_H_
#define HILBERT_H_
class Hilbert
{
public:
Hilbert(int dx,int dy)
{
nXDim = dx;
nYDim = dy;
int m = dx>dy ? dx : dy;
int nOrder = 1;
while ((1<<nOrder)<m) nOrder++;
pPointsX = new int[dx*dy];
pPointsY = new int[dx*dy];
nX = 0;
nY = 0;
nPoints = 0;
hilbert(nOrder, NORTH, EAST, SOUTH, WEST);
}
~Hilbert()
{
if (pPointsX) delete []pPointsX; pPointsX = NULL;
if (pPointsY) delete []pPointsY; pPointsY = NULL;
}
int *GetX() { return pPointsX; }
int *GetY() { return pPointsY; }
int Count() { return nPoints; }
private:
int nXDim,nYDim;
int *pPointsX;
int *pPointsY;
int nPoints;
int curvesize(int ord) { return (1<<ord) - 1; }
static const int NORTH=0, EAST=1, SOUTH=2, WEST=3;
int nX,nY;
void move(int d)
{
// Move one unit in direction d from point lastpoint.
switch (d)
{
case NORTH: nY--; break;
case EAST: nX++; break;
case SOUTH: nY++; break;
case WEST: nX--; break;
}
}
void hilbert (int i, // order of Hilbert curve to be drawn
int front, // direction at front
int right, // direction at right
int behind, // direction at back
int left) // direction at left
{
if (i == 0)
{
if (nX<nXDim && nY<nYDim) // cut to image only
{
pPointsX[nPoints ] = nX;
pPointsY[nPoints++] = nY;
}
}
else
{
hilbert(i-1, left , behind, right , front ); move(right );
hilbert(i-1, front, right , behind, left ); move(behind);
hilbert(i-1, front, right , behind, left ); move(left );
hilbert(i-1, right, front , left , behind);
}
}
};
#endif
There are a lot of changes in the project I will write more about it soon, lightcuts works great,
some new images generated (including our new kitchen visualization designed by my wife):


