我目前正在研究光线投射和体素,这是一个很好的组合。 Sebastian Scholz的Voxelrenderer很好地实现了这一点,但也使用了OpenGL。我想知道他的配方是如何工作的;你如何使用OpenGL与光线投射和体素?光线投射的想法是不是为每个像素(或线,即在Doom中)投射光线然后绘制结果?
答案 0 :(得分:5)
所提到的raycaster是Voxelrenderer,即一种可视化体积数据的方法,如存储在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);
finalize
和combine
取决于数据的类型以及您想要显示的内容。例如,如果要集成密度(如在X射线图像中),combine
将是求和操作并完成归一化。如果你想要一个云,你可以在体素之间进行alpha混合。
答案 1 :(得分:0)
体素空间中的光线投射不会使用像素,效率会很低。
你已经有了一个数组来说明哪些空格是空的,哪些空格有一个体素立方体。
因此,快速版本正在追踪一条线,该线检查线上方向上每个体素的emptimess,直到它达到一个完整的体素。
对于每个读操作,这将需要来自存储器的几百个读操作和光线矢量的2-3次乘法。
读取体素的十亿个记忆位置需要大约1秒,因此几百个非常快并且总是在一帧内。光线投射通常使用optmizations来检测空间中的小数位数,其中数学公式为星形,其中网格顶点基于其边界框然后是网格,而在体素中,它只是逐步检查整数数组中的直线,直到您找到一个无效的。