一种适用图形硬件的分格化方法

文档序号:6355190阅读:290来源:国知局
专利名称:一种适用图形硬件的分格化方法
技术领域
本发明主要是提出一种适用图形硬件实现的分格化(Tessellator)方法,可以高 效地实现曲面细分的功能。本发明提出的分格化方法,尽量避免占用硬件资源较多地乘除 法操作,适合采用图形硬件电路来实现,属于适用于图形硬件的曲面细分设计方法领域。图形处理需要巨大的计算能力,来实现图形的实时产生。一个三维应用或游戏场 景中,为了获得细腻,真实的显示效果,通常将物体表面分格化后,产生数万到数百万个多 边形,通常为三角形,再进行染色,贴图等处理。要实现这样数量巨大的多边形进行实时处 理,其性能要求是较高的,需要各种图形加速器硬件的支持,其中包括对曲线和曲面计算的 硬件支持。图形硬件所绘制的是最基本的图元,即点、直线和多边形(通常是三角形),一个 平滑的曲面是通过使用大量微小的多边形来模拟的。曲面细分(Tessellation)就是把一 个曲面进行分格化以产生一系列多边形的技术。在较早的图形处理系统中,曲面细分是靠 软件来实现的,而最新的图形处理器则包含了完成曲面细分的硬件,从而提高了曲面渲染 的速度。
背景技术
曲面细分的思想可以追溯到20世纪50年代G. Miam提出的多边形割角算法,1974 年,Chaikin提出的曲线细分方法。1978年Catmull与Clark, Doo与Sabin分别将三次和 二次均勻B样条曲面推广到任意拓扑,提出了著名的Catmull-Clark细分和Doo-Sabin细 分算法。1987年美国华盛顿大学的Loop发明了著名的Loop细分模式,该方法至今仍是最 常用的细分模式之一 ;1990年,Dyn等提出了插值三角网格顶点的蝶式(Butterfly)细分; 同年,Kobbelt提出了插值四边形顶点的KcAbelt细分;1997年,Peters与Reif给出了基 于四边形网格的中边细分;2000年,Kobbelt又给出了对偶的三角网格细分模式^细分, Labsik与Greiner在此基础上提出了插值^细分;2002年,Loop给出了基于三角网格的
三分细分格式;2003年Mam与Loop提出了基于三角网格和四边形网格的混合细分。在Directll和OpenGL 4. O中最显著的变化就是增加曲面细分(Tessellation) 功能,也就是这个功能将由图形处理器(GPU)来实现。这样由图形硬件来实现LOD (Level Of Detail)的表面细化,既能达到非常真实细腻的画面效果,同时又尽可能地发挥硬件的 性能。在DirectX 11中曲面细分(Tessellation)功能是由三个功能模块实现的, 即Hull Shader (外壳着色器),Tessellator (分格化处理单元)和Domain Shader (域 着色器)。在DirectX 11中,Hull Shader和Domain Shader都是可编程的着色器,而 Tessellator则完全是由固定硬件算法实现的加速器。图1. Direct3D 11流水线结构示意图如图1所示,Hull Shader负责收集图形曲面的参数信息,如控制点等用来定义曲 面的参数变量。HS根据由控制点生成的曲面表达式产生一系列的面片(surface patches)以及与之相对应的LOD信息。Tessellator是一个固定功能模块,它并不需要曲面的控制点信息,它的输入是面 片和对应的LOD信息。Tessellator根据LOD信息将面片细分成若干个四边形或三角形。 如果是四边形还会进一步分解成两个三角形。这些三角形的顶点伴随着它们在面片中参数 坐标等分格化信息送入下一级处理。Domain Siader根据面片中的参数坐标对每一个三角形的顶点进行单独处理,并 从其附带的分格化信息中进行计算。Domain Siader会计算出每个顶点所对应的信息,包 括坐标数据、纹理坐标等,并将该顶点和对应的顶点信息向下一级传送。后面的DirectX 11中各模块根据顶点信息进行各种图形操作,包括投影变换、 三维剪裁、视口变换、图元装配、光栅化、像素染色和颜色混合等操作,最终在屏幕上呈现出 所要求的曲面表面。曲面细分的方法虽然很多,因为有很多的乘除法操作,硬件实现效率较低,我们提 出的方法,主要采用定点整数的加法和比较运算,尽量避免乘除法操作,适用于硬件实现。

发明内容
本发明的目的在于提出一种在图形处理器中适用于硬件实现的高效曲面细分的 方法。本发明针对Direct 11流水线结构中的Tessellator,提出该模块的核心实现方法。Tessellator的输入是曲面的面片(surface patches),以及与之相对应的LOD信 息。每一个面片都是由内部的规则矩形和外部的不规则边界构成,如图2所示。图2面片结构示意图面片的内部规则矩形可以根据LOD信息划分成很多小的矩形网格。如图2所示, 面片中规则矩形的高度LOD值LODh = 5,宽度LOD值LODw = 10,因此面片中规则矩形可以 划分成50个矩形网格。面片的四个边界构成了四边形,且每边的LOD值可以各不相同。如 图2所示,左边界的LOD值LODf = 8,右边界的LOD值LODk = 7,上边界的LOD值LODt = 8, 下边界的LOD值LODb = 5。在本发明方法中,对面片中规则矩形的网格顶点是按从左向右,从下到上的顺序 进行编号。对面片边界上的顶点是从按左下角开始,沿顺时针方向进行编号。分格化方法的 具体实现方法可以分为两个分支面片中规则矩形的分格化和面片边界区域的分格化。以 下是两个分支方法的具体说明。3. 1面片中规则矩形的分格化面片中规则矩形的分格化分为两个步骤。首先是要将面片的内部规则矩形分成若 干个矩形块(rectangle),每个矩形块中包含若干个矩形网格(mesh)。这一步骤要求尽量 减少向下一级传送的矩形块数量,同时又能保证下一步处理的运算量适当。图3面片内部规则矩形分成矩形块示意图如图3所示,每个矩形块是由两行三列共6个矩形网格构成,因此每个矩形块包括 12个网格顶点。为了使划分方法简便,规定划分的顺序为从底向上,从左向右,依次进行。 在最顶上的矩形块和最右边的矩形块可能会与其他矩形块不同,如图3所示。该步骤的伪 代码如下所示Algorithm Tessellate—Mesh(LOT)训,LODh, bw, bh);
1.for(i=0; i<LODw; i=i+bw) {
2.cw = min((LODw - i), (bw + 1));
3.forG=0;j<LODH;j=j+bh){
4.ch = min((LODH - j), (bh + 1));
5.if(bw<=cw) {
6.if(bh<ch)
7.Generate—Rectangle(i,j,bw, bh);
8.else
9.Generate—Rectangle(i, j, bw, ch);
10.}
11.else{
12.Generate_Rectangle(i, j, cw, LODh);
13.break;
14.}
15.}
16. }在上面的伪代码描述中,LODw* LODh分别是面片内部规则矩形的宽度和高度LOD 值。而W和W1分别是矩形块的宽度值和高度值。在上面的方法描述中,都是整数操作,且 只有加法和比较操作,没有乘法和除法,使得硬件实现设计简单。其次要对每个矩形块进行处理。即从矩形块中分离出矩形网格,并将每个矩形网 格分成两个三角形。具体实现方法的伪代码如下所示
Procedure Generate_Rectangle(\, j, w, h); 1. for(n=0 ; n<w; n++) {
2.for(m=0; m<h; m++){
3.vl = (n+i)*( L〇DH+l)+m+j;
4.v2 = (n+i)*( LODH+l)+m+l+j;
5.v3 = (n+l+i)*( LODH+l)+m+j+l;
6.v4 = (n+l+i)*( LODH+l)+m+j;
7.Build_Triangle(vl, v2, v3);
8.Build一Triangle(vl, v3, v4);
9.}—
10. }在上面的伪代码描述中,虽然使用了乘法运算,但可以使用n*(L0DH+l)和 (n+l)*(L0DH+l)这样两个简单的计数器来实现累加运算。因此,也可以在硬件实现中不使 用乘法器。接下来BuilcLTriangle步骤将三角形的顶点坐标,从原来在内部规则矩形的节 点编号转换为在面片中的参数坐标lu,v,w},并计算相应的分格化数据信息。在Tessellate Mesh步骤中,每次循环都能得到一个矩形块。而在Generate_ Rectangle步骤中,每次循环都能把一个矩形网格分成两个三角形。在内部规则矩形细分 中,这两个步骤总共循环L0Dw*L0Dh次,每次都只有定点数加法和比较操作,因此总的算法 复杂度为0(L0Dw*L0Dh)。又因为面片中的规则矩形中矩形网格的数量是L0DW*L0Dh个,所
5以该方法性能是最优的。3. 2面片边界区域分格化面片边界区域分格化方法稍显复杂一些,目的是要将面片的边界与内部规则矩形 之间的空白区域用三角形“缝合”起来,如图2所示。在本方法中绝大多数情况下只需要定 点数加法运算和比较操作,乘法运算只需要在初始时使用一次即可。面片边界区域分格化 需要两个步骤。首先对四个边界区域进行分别处理,包括初始化一些参数信息等,该步骤的 具体实现的伪代码如下所示
Algorithm Tessellate_External(LOOL, LODT, LODr, LODb, LODh, LODw);
1.stride = 1; Ns = O, Ne = O;
2.Border_Stitching(LOOu LODh, stride, Ns, Ne);
3.stride = LODh+ 1; Ns += LODl, Ne = LODh;
4.Border_Stitching(LOOi, LODw, stride, Ns, Ne);
5.stride = -1; Ns += LODT, Ne = (LODh+1)* (LODw+1)-1;
6.Border_Stitching(LOOR, LODh, stride, Ns, Ne);
7.stride = —LODh-I; Ns += LODr, Ne = (LODH+l)*LODw;
8.Border_Stitching(LOO^, LODw, stride, Ns, Ne);在上面的伪代码描述中,分别对面片的四个边,从左边起,按顺时针方向,依次进 行边界区域的分格化处理。其中,Ns是面片边界上的节点索引值,Ne是面片中规则矩形边 界的节点索引值,如图2所示。其次要对面片的边界和与之相对的规则矩形的边界进行分格化处理,即三角形 “缝合”处理。该步骤具体实现的伪代码如下所示
Procedure Border_Stitching(LOO^, LODi, stride, Ns, Ne);
1.integer range = LODe * LOD1;
2.integer iPos = O, ePos = O, iStep = LODe, eStep = LODi;
3.make_Triangle(Ns, Ns+1, Ne);
4.ePos += eStep;
5.Ns +=1;
3. while (iPos < range 丨丨 ePos < range) {
5.if ((iPos + iStep) < (ePos + eStep)){
6.Make—Triangle(Ns,Ne, Ne+stride);
7.iPos += iStep;
8.Ne += stride;
9- }
10.else{
11.Make—Triangle(Ns,Ns+1, Ne);
12.ePos += eStep;
13.Ns+=1;
14.}
15.}在上面的伪代码描述中,大多数情况下只有定点数加法和比较运算。在该步骤初 始的时候需要用到一次定点数乘法,由于是给定参数的乘法运算,因此,也可以将乘法结果由Hull Siader传过来,这样可在此省去乘法器设计。接下来在Makejriangle步骤中,将 三角形的顶点坐标,从原来在内外边界中的节点索引值转换为在面片中的参数坐标lu,ν, w},并计算相应的分格化数据信息。在Tessellate_External步骤中,依次对四个边界区域进行初始化处理。而在 Border_Stitching步骤中,每循环一次,都可得到一个三角形,总共循环LODfLOD1次,因此 该方法的计算复杂度为O(LODfLOD1)。又因为每条边界对应的三角形数为LODfLOD1个,所 以该方法的性能是最优的。


图1. Direct3D 11流水线结构示意2.面片结构示意3.面片内部规则矩形分成矩形块示意4.分格化方法硬件实现示意图
具体实施例方式5.1硬件结构设计采用本方明提出的分格化处理方法所设计的硬件结构如图4所示。在该硬件结构 中,Tessellator内部首先用Branch模块接收从Hull Siader送过来的面片信息,包括面 片的内部规则矩形的宽度和高度LOD值,以及面片的4个边界的LOD值等信息。在Branch 模块内部处理这些数据信息,然后将数据信息打包分为两条支路传送。这两条支路分别进 行面片的内部规则矩形的分格化和面片边界区域的分格化处理。图4分格化方法硬件实现示意图在面片的内部规则矩形的分格化这一分支中,TeSSellate_MeSh模块接收从 Branch模块传来的面片的内部规则矩形的宽度和高度的LOD值仏01\和LODh),以及矩形块 的宽度和高度值(bw和Wi)。在TessellaLMesh模块内部处理中,将面片的内部规则矩形 划分为若干个矩形块。在TessellaLMesh模块内部状态机中,每一个节拍都能得到一个矩 形块,然后将该矩形块向下一级传送。Generate_Rectangle模块接收从iTessellate_Mesh模块传来的矩形块的起始点 信息(i,j)和宽度高度信息(w,h)。在Generat^Rectangle模块内部处理中,首先将矩形块 分解为若干个矩形网格(mesh),紧接着将单个矩形网格划分为两个三角形。在Generate Rectangle模块内部状态机中,每个节拍都能得到两个三角形,然后将这两个三角形的顶点 信息向下一级传送。Build_Triangle模块接收从Generate_Rectangle模块传送来的三角形的顶点 数据信息(V0、VI、V2)。因为一个节拍会有两个三角形传送过来,因此设计两个BuilcL Triangle模块接收信息。BuiIcLTriangle模块内部处理中,将三角形的顶点坐标,从原来 在内部规则矩形的节点编号转换为在面片中的参数坐标lu,ν, w},并计算相应的分格化数 据信息。在Generat^Rectangle模块内部状态机中,每个节拍都能计算出三角形三个顶点 的参数坐标,然后将包含该信息的分格化数据向下一级Domain Shader传送。在面片边界的分格化这一分支中,Tessellate_External模块接收从Branch模块传来的面片的边界信息,包括面片的内部规则矩形的宽度和高度LOD值,以及面片的4个边 界的LOD值等信息。在Tessellat^External模块内部处理中,计算出4个边界分格化所 需要的参数,如内外边界起始节点索引值和步长等信息。在Tessellat^External模块的 内部状态机中,每个节拍能计算出一条边界区域分格化所需要的初始数据信息,然后向下
一级传送。Border_Stitching模块接收从iTessellate_External模块传送来的内部和外部 边界LOD值(LODjP L0DE),以及步长(stride)、内部和外部边界起始节点索引值(队和队)。 在BorderJtitching模块中,将内部和外部边界区域用三角形逐个“缝合”。在Border_ Pitching模块状态机中,每个节拍都能得到一个三角形,以及三个顶点在内部和外部边界 中的索引值,然后将该信息向下一级传送。Makejriangle模块接收从BorderJtitching模块传来的三角形的三个顶点在 内外边界中的索引值等数据信息(Ne,Ns, Ne/Ns+Ι)。在MakeJriangle模块内部处理中, 将三角形的顶点坐标,从原来在内外边界中的节点索引值转换为在面片中的参数坐标lu, v,w},并计算相应的分格化数据信息。在Makejriangle模块内部状态机中,每个节拍都 能计算出三角形三个顶点的参数坐标,然后将包含该信息的分格化数据向下一级Domain Shader 传送。根据本方明方法所设计Tessellator的硬件结构采用流水线工作方式。在流水线 满负荷情况下,每个节拍可以输出3个三角形。在具体实现中,绝大多数运算都是定点数加 法和比较操作。在本方法中只有少数运算需要用到乘法操作,可以通过一些方式避免,如前 所述。本方法在设计时充分考虑了硬件的实现,比较容易提高运算并行性。5. 2仿真结果验证依据本发明方法编写了相应的C语言仿真程序,分别对面片的内部规则矩形和面 片边界区域进行了分格化。设定面片的内部规则矩形的面片中规则矩形的高度LOD值LODh =5,宽度LOD值LODw = 10。每个矩形块初始设为高度为2,宽度为3。对面片的内部规则 矩形分格化所结果如表1所示表1面片内部规则矩形的分格化结果
权利要求
1. 一种适用图形硬件的分格化方法,该方法包含内部矩形分格化和边界区域分格化两 部分,在划分过程中(除了初始化时)仅使用了定点整数的加法和比较运算,且内部分格化 时可以按照硬件配置进行并行划分,分格化的结果包括有序的顶点索引和相应的参数坐标 {u,ν};其中边界区域分格化实现方法为将面片边界的LOD值与对应的内部规则矩形边界 的LOD值相乘,用该乘积作为判断循环终止的条件,且面片边界上节点索引值和内部矩形 边界上节点索引值按各自步长依次交替增长,步长均为定点整数;内部矩形分格化实现方 法为将面片的内部规则矩形首先划分为若干个矩形块,接着将每个矩形块划分为若干矩 形网格,最后将每个矩形网格划分为两个三角形。
全文摘要
“一种适用图形硬件的分格化方法”发明,属于适用于图形硬件的曲面细分设计方法领域。为了解决图形曲面细分加速处理中将图形表面细分为更小的多边形时,硬件实现的效率问题,提出了此方法。方法将曲面面片分格化分解为面片的内部矩形分格化和边界区域分格化两部分,减少了硬件实现中消耗时间较长的乘除法操作,采用定点整数的加法与比较操作实现。该方法主要用于图形处理器中曲面细分的分格化处理单元。该方法的提出可以有效提高硬件实现的效率。
文档编号G06T17/20GK102096948SQ20111004801
公开日2011年6月15日 申请日期2011年3月1日 优先权日2011年3月1日
发明者刘海, 曹小鹏, 董梁 申请人:西安邮电学院
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1