实时绘制基于LOD的地形相关技术

LOD(levels of etails细节层次)是解决大规模地形实时渲染的一项关键技术。在地形中实现LOD技术后大大加速了地形的渲染。其基本思想是:对地形生成具有不同层次(不同分辨率)的多个版本,在绘制地形时依据视点来选择合适的层次细节进行绘制。本文用基于四叉树构建的地形来实现相关Lod算法,有关四叉树构建地形的技术可参考“引擎技术研究之地形技术”。

 

 

 

 

可把全部叶子节点保存在数组Leaf,查找邻接节点时可遍历Leaf获取,可根据以下条件判断四个邻接节点:

[2]=[0]  &&  [3]=[1]

[0]=[1]  &&  [2]=[3]

[0]=[2]  &&  [1]=[3]

[3]=[2]  &&  [1]=[0]

2根据视点选择层次细节

先计算每个叶子节点与摄像机视点的距离distance,为每个节点设计一属性Unit作为分辨率,依据distance设置Unit,如:

if (title->distance<50.0) {      title->unit=1;        }

else if (title->distance<100) {    title->unit=2;   }

else if (title->distance<200) {     title->unit=4;        }

Unit值适宜设置为2n次幂(1 2 4 8 16   …….,如图所示:

 

3构造节点的三角形

首先确定当前节点是叶子节点title,再根据叶子节点的ditance设置其Unit值,每行的索引数(像素)为MESH_WIDTH+1,节点里每行或每列的网格数corner[1]-corner[0],n[4]保存每个块的四个顶点索引值。

有两种构造情况,一是有某一邻接节点与当前节点的Unit不等时,二是四个邻接点的Unit均与当前节点相同。

A

先处理第一种情况,若Unit=1则一个网格作为一个块构造两三角形,Unit=2,2x2个网格作为一个块构造两个三角形,以此类推。实现如下:

for(int j=0;j<wide;j+=title->unit)

{                  

    for(int i=0;i<wide;i+=title->unit)  //遍历每个块     

        {                                   

            n[0]=title->corner[0]+j*numrow+i;//设置块四个顶点索引值

            n[1]=n[0]+title->unit;

            n[2]=n[0]+numrow*title->unit;

           n[3]=n[2]+title->unit;

       

                    index[m_NumIndex++]=n[0];

            index[m_NumIndex++]=n[2];

            index[m_NumIndex++]=n[1];//左下三角形

          

     index[m_NumIndex++]=n[1];

           index[m_NumIndex++]=n[2];

           index[m_NumIndex++]=n[3];//右上三角形

}

}

index为指向索引缓冲区内存的指针m_NumIndex为索引数量,以上可完成块的三角形构造。

B现处理第二种情况。块的三角形分两部分构造,一是正常的,下图黑色三角形。

二是交界处需特殊构造的三角形,如下图红色线条三角形:

                              

1)现画正常的三角形,遍历每个块:

for(int j=0;j<wide;j+=title->unit)

{       

for(int i=0;i<wide;i+=title->unit)  //遍历每个块     

        {                                   

            n[0]=title->corner[0]+j*numrow+i;//设置块四个顶点索引值

            n[1]=n[0]+title->unit;

            n[2]=n[0]+numrow*title->unit;

           n[3]=n[2]+title->unit;

    先处理上边界:

        if ((title->neigbour[2]!=NULL&&title->neigbour[2]->unit>title->unit)

        &&(j<wide&&j>=wide-title->unit&&(i/title->unit)%2==1)) //处理序号为单数的块

                        

                          if (!((title->neigbour[1]!=NULL)&&(title->unit<title->neigbour[1]->unit)

     &&(i>=(wide-title->unit))&&(j>=(wide-title->unit))))

                          {  //若上邻接点和右邻接点Unit均大于当前Unit,则不构造如图所示红色三角形

                           

     index[m_NumIndex++]=n[0]; //画块里右下三角形

                       index[m_NumIndex++]=n[3];

                       index[m_NumIndex++]=n[1];

                 }

              }

              else if ((title->neigbour[2]!=NULL&&title->neigbour[2]->unit>title->unit)

     && (j<wide&&j>=wide-title->unit&&(i/title->unit)%2==0)) //处理序号为双的块

              {  

                     if (!((title->neigbour[3]!=NULL)&&(title->unit<title->neigbour[3]->unit)

&&(i<=title->unit)&&(j>=(wide-title->unit))))

                   {  //若上邻接点和左邻接点Unit均大于当前Unit,则不构造如图所示红色三角形

                          

                       index[m_NumIndex++]=n[0];// 画块里左下三角形

                       index[m_NumIndex++]=n[2];

                       index[m_NumIndex++]=n[1];

                   }                                               

              }

              else 处理下边界

              else 处理左边界

              else 处理右边界

              else 一般构造

   {

                       index[m_NumIndex++]=n[0];

                       index[m_NumIndex++]=n[2];

                       index[m_NumIndex++]=n[1];

 

                       index[m_NumIndex++]=n[1];

                       index[m_NumIndex++]=n[2];

         index[m_NumIndex++]=n[3];  

   }

}//结束正常构造

 

2)构造节点交界处三角形

处理上边界:

if (title->neigbour[2]!=NULL&&title->neigbour[2]->unit>title->unit)

{    //上邻接点Unit大于当前节点

for (int k=0;k<wide;k=k+2*title->unit)

{

    n[0]=title->corner[2]+k;

         n[2]=n[0]+2*title->unit;

         n[1]=(n[0]+n[2])/2-numrow*title->unit;

         index[m_NumIndex++]=n[0];                

         index[m_NumIndex++]=n[2];

         index[m_NumIndex++]=n[1];

     }

}

处理下边界。。。

处理左边界。。。

处理右边界。。。

最终实现LOD的地形构造效果图

 

posted @ 2008-11-19 01:25  毛志谦  阅读(594)  评论(1编辑  收藏  举报