3D空间离散点的值可以视为一个3D标量场。标量场可视化的经典算法包括Marching Cubes算法(简称MC算法)和光线投射(Ray-casting)算法。前者将标量场转换为多边形片进行显示,后者通过光线投射算法直接进行显示。
一直以来,研究人员都追求如何快速的进行MC算法的计算,并将视线由传统的CPU转变到了GPU上。早期由于图形硬件的限制,导致Marching Cubes算法很难应用到GPU领域。经过研究人员的不断努力,提出了简化的Marching Tetrahedron方法,但其成像速度及质量较差。在GPU越来越通用化以后,通过应用Render To Texture和GPU上的流式缩减,在GPU上实现MC算法[35],并且达到实时运算的速度。7.1节中将重点阐述此方法的应用。
Ray Casting(光线投射)算法是Ray Tracing(光线追逐)算法的一个简化,它以屏幕像素作为光线的出发点,向标量场投射光线,并对光线经过的标量值进行积分,通过积分的结果决定像素的颜色、透明度并显示在屏幕。此算法如果利用CPU计算由于涉及到大量像素的操作,不具有实时性。所以大量的算法都基于GPU的计算。
下面将分别介绍两种算法并展示其在五轴数控仿真方面的应用。
GPU Marching Cubes算法
目前基于GPU的算法中,由于可以将所得到的结果直接进行渲染,不必经过CPU和GPU之间的交互,所以利用Histogram Pyramid(简称HistoPyramid)在GPU上进行流式缩减和扩展的算法能够在得到最高的性能[35]。
Marching Cubes算法
在标量场中提取等值面的算法中,文献[36]提到的Marching Cubes算法是目前应用最多的算法。它将一个大小为H*W*D的3D标量场表示为(H-1)*(W-1)*(D-1)个MC单元(图 7-1)组成的立体网格。每个单元置于8个标量值之中,其值可以通过算法应用需要对8个标量值进行处理。这样一个MC单元就有一个标量值,以及8个包围它的8个标量值。如果依次遍历这个立体网格,按照设定的阈值可以区分MC单元属于物体内还是外,再根据MC单元值和8个标量值的不同组合可以得到组成这个MC单元的多个三角形的形状。所有的三角形组合起来就可以得到标量场等值提取所表示的面。
|

|
|
图 7-1 MC单元,每个单元含8个标量值abcdefgh
|
图 7-1是一个典型的MC单元,根据阈值将8个标量值分为了里(bd)和外(acefgh)。MC单元根据8个标量值的处于内和外的不同,具有256种组合。这些组合可以通过基本的15种组合经过变换得到。由于每个单元的计算可以单独计算,所以MC算法并行性较高,能够应用GPU进行加速。
在图 7-1所示的这种MC类型中,平面和MC单元相交形成了一个四边形,阈值的取值和标量值的值决定了交点所在位置。例如采用线性插值,当阈值iso=0.4,c=0.8,d=0.32时,点P(c,d)在直线cd上,直线CD:CP=0.4。如果采用取中间点算法,则得到P(c,d)在直线cd的中点上。但这种取中点的算法没有用线性插值所得到的结果平滑,而且由于目前的GPU运算速度很快,线性插值的性能损失可忽略不计。
HistoPyramid
HistoPyramid是一种类似于三角金字塔的结构,其最底层结构为输入流,输入流中的一个元素代表了某种特定类型的数量,在金子塔的顶端,代表了所有输入流元素所有类型的数量的和,这个和决定了输出流元素的数量。
如果输入流中的元素代表了0个特定类型,则这个输入流元素就被丢弃,这样的生成输出流就被压缩了。如果输入流元素代表了1个以上的特定类型,则在输入流元素中会有1个以上的元素输出,这样就实现了数据的扩张。
HistoPyramid有两个不同的阶段。第一个阶段创建一个HistoPyramid,它的数据结构类似于MipMap,为金字塔型,其计算方式也类似于MipMap的计算,只是将MipMap的平均值算法改为了求和算法。图 7-2是真实显存中的数据。每一级的大小都是前一级的1/4,直到大小变为1*1为止。最底层的一级称为"基础层",最上层的一级称之为"顶层"。
第二个阶段为生成输出流阶段。输出流的生成逆向的从"顶层"向下查找,直到最后在"基础层"中找到输入流中对应元素的索引后,在根据特定规则生成相应元素。
|

|
|
图 7-2 Histogram Pyramid 1-4级
|
构造基础层
由于目前的显卡不能渲染到3D贴图,或者通过软件实现渲染速度很慢,所以在构造基础层时将提供的标量场3D贴图进行平坦化,使之成为一个标准的2D贴图。由于标量场的一个元素中仅存储有一个float数据,而显卡在处理2D贴图时按照传统图形应用的RGBA像素进行提取,一次性可以取得四个数据。所以将标量场中每四个相邻数据存储到一个RGBA像素中,可以大大节约存储空间,并且得到更高的效率。
每一个RGBA像素代表了2*2*1个MC单元,所以获得一个像素所代表的4个MC单元的分类,需要提取3*3*2个MC单元的边角的值。阈值的大小和MC单元边角的标量场的数据决定了MC单元的分类和所需三角形的数量。为了减少存储空间,由于最多需要15个顶点就可以表示一个MC单元,一个RGBA像素可以利用整数部分存储顶点数量,利用小数部分存储MC单元的类型。这样GPU的流式缩减操作可以将整数部分保留,进行加法,得到最终输出内的顶点的数量。当在基础层决定顶点的类型时,将小数部分提取出来即可。
流式缩减
执行流式缩减操作将得到顶点的数量。在基础层中已经计算好每个MC单元所拥有的顶点数量,将其相加即可得到所有的顶点。
在GPU上实现此操作需要进行多步。此操作类似于生成MipMap的计算:第n张贴图的边长是第n-1张贴图边长的1/4大小。第n张贴图的某一个像素点(x,y)的值由下式决定:
|

|
(7- 1)
|
当最后一张贴图的边长为1*1时,流式缩减操作结束。由于将顶点数量存储在RGBA中,此时仍不能得到顶点总数量。此时,存储的RGBA值将会传回CPU,并将其RGBA值相加,得到总数量t。
|

|
|
图 7- 3 HistoPyramid计算结果
|
下面以一个简化的HistoPyramid为例(图 7- 3)介绍流式缩减操作。 BaseLevel含有16个元素,将红框中的4个数据相加得到2,存入level=1的(0,0)位置,其他12个元素按照此规则进行。此后level=1的所有元素相加,得到顶层的数值10。如果以RGBA进行存储,则进行到level=1时就要将数据传回CPU,然后CPU将RGBA的值相加,得到最终元素个数10。
流式扩展
此例中计算得知最终的output中有10个元素。要得到这10个元素,首先根据得到的总元素个数t生成一个k值列表,范围从0到t-1以1为步进递增。
从k值得到最后的坐标和序号的过程叫做"遍历"。设当前k值为m,当前层数为l,顶层为t,当前像素位置为p。
初始时l=t,k=m ,p指向最顶层元素,此时只有一个元素。
l=l-1,p指向l-1层的中心位置,其附近有4个值,记这四个值为a,b,c,d。四个数值可以得到如下数值范围:
|

|
(7- 2)
|
然后得到k所在的范围。例如如果k在C范围内,则我们将p指向c元素,并且将k减去范围C的起始范围,这里k=k-(a+b)。
重复过程2,直到l=0
此时p指向k所对应的输入元素的索引,k表示元素的第k+1个值。例如k指向的输入中包含两个元素R,S。当k=0时代表输出元素中的元素是R,k=1时代表S。
以图 7- 3为例,l=t,k=4时,第一次从顶层出发,k=4不变,p指向level=1的中心。此时a=2,b=3,c=1,d=4。得到4个范围:
A=[0,2],B=[2,5),C=[5,6),D=[6,10)
k=4落到B区间中。此时k=4-2=2,l=t-1=1,p指向元素3。
p在level=0的图中得到a=0,b=1,c=0,d=2,此时得到4个范围:
A=[0,0),B=[0,1),C=[1,1),D=[1,3)。
k=2落到区间D中。此时k=2-1=1,l=l-1=0,p指向元素2
此时l=0,结束遍历。剩余的k=1表示输出元素k=4时输出输入元素坐标(3,1)中的第二个元素。
通过计算k=3和k=4的值可以发现,其都指向输入元素坐标(3,1),但其输入元素序号不同,这样就实现了流式扩展。
注意输入元素中值为0的部分在输出元素中并没有被输出,这样就实现了数据的压缩。
HistoPyramid应用于MC算法
HistoPyramid应用重点在于基础层的结构。在MC算法中,涉及到MC单元的顶点数量和单元类型。将浮点型数据的整数部分存储顶点数量,小数部分存储单元类型即可。建立好基础结构以后,OpenGL执行多遍渲染以便执行流式缩减,将基础层的整数部分相加,得到三角形的数量总和t。此后,CPU根据t创建一个GPU输入的缓冲区存储k值,大小即为t。输入缓冲可以用Vertex Buffer Object实现。此外,还需要创建一个大小为t的输出缓冲区。
|

|
|
图 7-4 Marching Cubes生成包络面
|
GPU将对缓冲区的每个k值进行遍历操作。每一次遍历完成后会得到MC单元位置和顶点索引。这时再查找基础层里面对应MC单元存储的单元类型,进行查表。MC单元的类型及顶点数量存储在一个256*16的2D贴图中,其中横坐标的256代表256种类型,16代表15种MC基础类型。由于GPU在存储时按照4的整数倍存储效率最高,所以用16来代表15种基础类型,剩余一个可忽略。这样就可生成MC单元的顶点,根据阈值通过插值可以得到顶点坐标。
得到的顶点坐标可直接应用于GPU的三角形渲染,只需要将顶点连接起来,并赋予相应的颜色值和法线坐标(应用于光照)即可。图 7-4是使用MC算法生成的复杂曲面的包络面,体数据分辨率256*256*256,8800GTS上可达40fps以上。