实时绘制基于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的地形构造效果图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值