After a bit of experimenting with the boost::round functionality, the solution to the numeric instability problem was (of course) a lot simpler. The current implementation runs at 25 fps for a 600×600 resolution – pure software rendering.
If you don’t know anything about volume rendering or voxels, what you can see here could give you an important insight: it’s interesting to see how a fundamental property of rendering discretized fields already shows: I used a 64x64x64 (that’s 262144 little cubes) data field for these renders. When I use a bigger field (128x128x128), this hardly impacts performance. A bigger chunk of memory must be allocated to hold the data, but that’s about it: we’re still shooting the same amount of rays.
Compared to traditional methods, this is a difference. If you up the polygon count, this will have an impact on performance: there’s simply more items to check for intersections, more polygons to transform to screen space, … so all your loops will take longer to complete.
If you’re somewhat underwhelmed by these pictures, remember that this is not a cube with textures applied to it.
Next step is sparse voxel fields and voxels with opacity, using ray marching. After that, I’ll probably implement DDA to know which voxels we’re visiting, to speed up color accumulation. Some basic shading would be nice too. I can store whatever I want in a voxel :)