我目前在研究射线追踪和体素,这是一个很好的组合。Sebastian Scholz开发的Voxelrenderer实现得非常好,但也使用了OpenGL。我想知道他的公式是如何工作的;如何在射线追踪和体素中使用OpenGL?难道不是为每个像素(或线条,例如在Doom中)投射一条射线,然后绘制结果吗?
我目前在研究射线追踪和体素,这是一个很好的组合。Sebastian Scholz开发的Voxelrenderer实现得非常好,但也使用了OpenGL。我想知道他的公式是如何工作的;如何在射线追踪和体素中使用OpenGL?难道不是为每个像素(或线条,例如在Doom中)投射一条射线,然后绘制结果吗?
vec4f prev_color;
for(i=0; i<STEPS; i++) {
p = ray_direction * i*STEP_DELTA;
voxel = texture3D(volumedata, p);
prev_color = combine(voxel, prev_color);
}
final_color = finalize(prev_color);
finalize
和combine
取决于数据的类型和您想要可视化的内容。例如,如果您想要集成密度(如X射线图像),则combine
将是一个求和操作,而finalize
将进行归一化。如果您想要可视化云,则需要在体素之间进行alpha混合。
在体素空间中进行射线投射不会使用像素,这样效率很低。
您已经有一个数组来表示哪些空间是空的,哪些有体素立方体。
因此,快速版本是跟踪一条线,检查线方向上每个体素的空置情况,直到它到达一个完整的体素。
这将从内存中读取几百个操作,并且对于每个读取操作需要2-3次光线向量乘法。
要读取十亿个体素的内存位置大约需要1秒钟,因此几百个将非常快,并且始终在帧内。
射线投射通常使用优化来检测空间中数学公式开始的分数位置,在网格顶点基于其边界框和网格的情况下,而在体素中则只需逐步检查整数数组中的线,直到找到非空为止。