基本概念
光线投射方法是基于图像序列的直接体绘制算法。从图像的每一个像素,沿固定方向(通常是视线方向)发射一条光线,光线穿越整个图像序列,并在这个过程中,对图像序列进行采样获取颜色信息,同时依据光线吸收模型将颜色值进行累加,直至光线穿越整个图像序列,最后得到的颜色值就是渲染图像的颜色。
为什么在上面的定义是穿越 “ 图像序列 ” ,而不是直接使用 “ 体纹理 ” ?原因在于,体数据有多种组织形式,在基于 CPU 的高级语言编程中,有时并不使用体纹理,而是使用图像序列。在基于 GPU 的着色程序中,则必须使用体纹理。这里所说的图像序列,也可以理解为切片数据。
尤其要注意:光线投射算法是从视点到 “ 图像序列最表面的外层像素 ” 引射线穿越体数据,而不少教程中都是糊里糊涂的写到 “ 从屏幕像素出发 ” ,这种说法太过简单,而且很容易让人误解技术的实现途径,可以说这是一种以讹传讹的说法!从屏幕像素出发引出射线,是光线跟踪算法,不是光线投射算法。
下面说说光线投射算法实现。首先要渲染出正向面深度图和背向面深度图,这是为了计算射线穿越的最大距离,做为循环采样控制的结束依据;然后在顶点着色程序中计算顶点位置和射线方向,射线方向由视线方向和点的世界坐标决定,其实射线方向也可以放在片段着色程序中进行计算。然后到了最关键的地方,就是循环纹理采样、合成。
每一次循环都要计算新的采样纹理坐标和采样距离,然后进行颜色合成和透明度累加,如果采样距离超过了最大穿越距离,或者透明度累加到 1 ,则循环结束。将合成得到的颜色值输出即可。
示例演示
下面我们就实现一个Ray Casting Demo。首先背向面深度渲染(backFace相关的shader),目的得到射线的结束位置。
然后进行Ray Casting渲染(Ray Casting相关的shader)。用到一个 3D texture存放体数据,一个2D texture存放射线结束位置(同帧缓存从前面的背向深度渲染得到),一个1D texture存放传递函数。工程代码下载。