光线投射体素和OpenGL

3

我目前在研究射线追踪和体素,这是一个很好的组合。Sebastian Scholz开发的Voxelrenderer实现得非常好,但也使用了OpenGL。我想知道他的公式是如何工作的;如何在射线追踪和体素中使用OpenGL?难道不是为每个像素(或线条,例如在Doom中)投射一条射线,然后绘制结果吗?

2个回答

5
所提到的光线投射器是一个体素渲染器,即一种可视化体积数据的方法,例如存储在3D纹理中的不透明度。Doom的光线投射算法有另一个意图:对于屏幕上的每个像素,找到地图的第一个平面表面并绘制该区域的颜色。现代GPU的光栅化能力使得这种使用光线投射器的方法已经过时了。
实时可视化体积数据仍然是特殊硬件完成的任务,通常在医学和地球成像系统中找到。基本上,这些都是大量的RAM(数十GB)持有体积RGBA数据。然后对于屏幕上的每个像素,通过体积投射一条光线,并沿着该光线集成RGBA数据。GPU Voxelrenderer通过片段着色器执行相同的操作;伪代码:
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);

finalizecombine取决于数据的类型和您想要可视化的内容。例如,如果您想要集成密度(如X射线图像),则combine将是一个求和操作,而finalize将进行归一化。如果您想要可视化云,则需要在体素之间进行alpha混合。


所以总的来说,光线投射是由GPU上的片段着色器完成的,对吧? - RobotRock
是的,这是唯一一个可以以明智的方式完成此操作的地方;嗯,也可以通过几何/顶点着色器发射点的组合来完成,但那样会很笨拙。 - datenwolf

0

在体素空间中进行射线投射不会使用像素,这样效率很低。

您已经有一个数组来表示哪些空间是空的,哪些有体素立方体。

因此,快速版本是跟踪一条线,检查线方向上每个体素的空置情况,直到它到达一个完整的体素。

这将从内存中读取几百个操作,并且对于每个读取操作需要2-3次光线向量乘法。

要读取十亿个体素的内存位置大约需要1秒钟,因此几百个将非常快,并且始终在帧内。

射线投射通常使用优化来检测空间中数学公式开始的分数位置,在网格顶点基于其边界框和网格的情况下,而在体素中则只需逐步检查整数数组中的线,直到找到非空为止。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接