3D地形编程——之GeoMipMap基础(5)

本文介绍了一种基于块的地形渲染方法,通过调整块边缘的扇形渲染来防止裂缝,并利用视截体裁剪减少不必要的GPU/CPU工作,同时探讨了如何通过Geomorphing平滑变换来减少细节级别变化时产生的突变。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

块的邻接结构的信息我们之前填充的,在块边缘的扇形被渲染时使用,展示如下:

 

//if this fan is in the left row, we might need to

//adjust its rendering to prevent cracks

if x==fHanlfSize

      fanNeighbor.m_bLeft= patchNeighbor.m_bLeft;

else

      fanNeighbor.m_bLeft= true;

 

//if this fan is in the bootom row, we might need to

//adjust its rendering to prevent cracks

if( z==fHalfSize )

      fanNeighbor.m_bDown= patchNeighbor.m_bDown;

else

      fanNeighbor.m_bDown= true;

 

//if ths fan is in the right row, we might need to

//adjust its rendering to prevent cracks

if( x>=( m_iPatchSize-fHalfSize ) )

      fanNeighbor.m_bRight= patchNeighbor.m_bRight;

else

      fanNeighbor.m_bRight= true;

 

//if ths fan is in the top row, we might need to

//adjust its rendering to prevent cracks

if( z>=( m_iPatchSize-fHalfSize ) )

      fanNeighbor.m_bUp= patchNeighbor.m_bUp;

else

      fanNeighbor.m_bUp= true;

 

//render the triangle fan

RenderFan( ( PX*m_iPatchSize )+x, ( PZ*m_iPatchSize )+z, fSize, fanNeighbor, bMultiTe x, bDeltail );

 

由填充一个单独的扇邻接结构,我们不需要改造块的邻接结构。扇的邻接结构是送到扇渲染函数的,用来找出是否任何顶点需要从渲染中移除。这些就是所有低级别渲染函数。现在我们简单的讨论类的高级Render函数,它是用户会用到的。我们由demo5_1走进这个世界!

 

Render函数

好了,我们刚才完成了我们简单的Geomipmapping的实现。你感觉兴奋激动了吗?我知道我是的!

 

在这个高级渲染函数中,我们需要循环遍历所有块调用RenderPatch函数,但是我们会有3个不同的块渲染循环。还记得我们的蛮力(brute force)实现吗?如果用户支持重纹理我们只需要一个渲染循环;不管怎样,如果用户不支持多重纹理,我们可能需要创建一个纹理图过程和细节图过程。2个不同的渲染过程对一个地形实现来说决不是好事情,然而,所以一个选项是避开细节映射过程在用户不支持多重纹理时。如果你从一开始挨着读这本书的每章那么你应该已经熟悉这个概念。你需要做的事只是循环遍历所有块并调用RenderPatch函数渲染它们。

 

这就完成了!我们完成了基础的Geomipmapping实现。看demo5_1(在CD里目录Code/Chapter5/demo5_1下)也看下demo的简单屏幕截图在图5.17中。在左边它展示了纹理/细节映射图像,在右边是相同图像的网格展示。注意在网格这边中,离你近的块有更多细节,离你远的细节较少。就是漂亮的CLOD算法!

 

修改存在的问题

是,是的,我知道。我们刚完成的Geomipmapping实现中有些问题。例如,除非你有真的最高端的显卡,你可能有经验在前面的demo是个非常差的帧速率。(我在GeForce 4 TI4600上测试这个demo,这是在写作时市面上最好的显卡,我得到稳定的4550帧每秒。)在地形块改变他们的细节级别时这个demo也受到突变的影响。我们讲修改所有这些而更多的在后续章节中,所以别担心!

 

给引擎增加一点动劲

首先,我想我们应该提升我们的实现。提升东西的速度很简单。它简单地关注于做一些视截体裁剪。

 

5.17

5.17 一个纹理和细节映射地形截图(左)和相同的网格图像(右),从demo5_1取得。

 

因为我们的地形被划分成很多块,我们最好打赌只用视截体为基准剔除那些块,也就是不需要特别多的测试。

 

再次的剔出你以前从未剔除的

在这我们将做些基础的视截体裁剪。给CCAMERA类增加些视截体计算功能,其中基于的一些信息在Mark Morley’s的文章“Frustum Culling in OpenGL”中,这是我在互联网上看到的最有效的视截体裁剪教程。(那篇文章你可以在下面网址找到http://www.markmorley.com/opengl/frustumculling.html.)是的我的承认,我的数学知识不是很好(注意这本书没有到处都是复杂的数学!),但是这也许是个好事――除非你是超级的数学迷恋者,在这情况下我可能应该期待一些反感的邮件。

无论如何,这里是些我们将要做的基础内容。我们会裁剪超出视截体的地形块(图5.18这里你需要一个直观的感受)这样我们排出任何额外的GPU/CPU工作避免浪费资源。(如果观看者看不到它,就没有渲染/更新它的必要。)

 

我们需要对视截体测试地形块。为了这么做,我们用轴对称包围盒(AABB)包围块。(实际上,我们让立方体边缘比块大些。)这时我们对视截体测试它。以计算块的尺寸,我们取得中心和缩放比例变量(看图5.19)。

 

5.18

5.18 视截体。

 

5.19

5.19 用立方体包围Geomipmapping的块,对视截体测试。

 

因为我们仅处理块的中心,需要把大小的一半用函数参数传递(用立方体的平截体做交集)以计算基于块的立方体的角。我们也能得到一些更精确的盒子,但是在我的裁剪实验中,需要额外的“空间缓冲区”那么观看者不会在地形中看到不和谐(比如一个块看的见一点但是无论如何也会被裁剪掉)。

 

现在你知道更多的关于裁剪和它对地形的实际使用,看demo5_2(在CD目录Code/Chapter5/demo5_2)并给你自己证明得到了多快的东西。例如,在图5.20中,超过910个左右快,我们只看到369个。在demo中,得到稳定的帧速(80120fps),并且这用的高度图是demo5_1中的2倍大小。

不是很低劣!

 

5.20

5.20 demo5_2的屏幕截图

 

今天突变,明天解决

下一个我们着手对付的问题比前一个更复杂。我们的目标是减少——甚至更好——清楚突变。有许多方法做这个,我会展示他们之中2个背后的理论。这些解决问题的实际实现方法还是会展示给你。

 

平滑它!平滑的更好!

首先解决突变问题的叫做Geomorphing。虽然这个名字听起来象一些在大型网格动画中预计听到的,这绝对不是对大型机器人故事做什么,而是有大量消除的能力。Geomorphing实际上是逐步平滑变换(morphing)一套多边形(象我们的Geomipmapping的块)顶点的过程,会改变它们的细节级别。就我个人而言认为mech thing听起来更有趣,但这实际上Geomprphing的意思更为有用些。

 

你问为什么这是有用?实际上这很简单。你看,当一个低细节级别的块,它近似许多高度区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值