虚拟贴图地形系统之概要设计

之前学习了虚拟贴图的理论知识,接下来该实践了,准备使用DX12写一个虚拟贴图的地形系统,在动手之前先把思路搞搞清楚,写写概要设计。

需求就按照Far cry 4的标准吧:

1.地形大小10km*10km

2.最高像素密度10pixel/cm

3.相机视距0.1m-10000m

首先我们先算一下满足上面的需求,虚拟贴图占用的磁盘空间是多少,假设每个像素占4个字节,大约需要363.8T的磁盘空间,先不说有没有这么大的磁盘空间,这美术的工作量也吃不消啊。以目前的技术要满足这个像素密度,只有使用tile平铺技术才能满足,我们可以用一张贴图,反复的平铺到地形上,这样像素密度可以达到要求,但表现效果肯定是很糟糕的。为了增强表现效果通常我们会使用多张贴图进行混合做为地形的基本纹理。而且也有很多tile技术可以减轻因为tile平铺引起的视觉重复比如wang-tile。

之前的显卡计算能力很弱,所以很多时候我们会将结果存储到贴图中,比如lightmap贴图,这样可以减轻GPU的计算压力。现在GPU发展的速度远远超越了磁盘及内存的发展,我们应该意识到通过GPU降低IO的压力将会成为一个新的趋势。Procedural virtual texturing其实就是响应这个趋势,Procedural virtual texturing本质上和虚拟贴图没有区别,它更多的是解决如何用程序计算来替代原始的贴图。比如我们都知道混合地形纹理,需要一张mask贴图,如果我们可以通过地形网格的程序化参数自动计算mask,这样就不再需要mask贴图了。Procedural virtual texturing追求的是地形系统可以使用不同的shader,比如有些地方可以混合8张贴图,有些地方可以混合4张贴图,有些地方使用视差贴图,有些地方不使用视差贴图,这里我们就不详细的讨论程序化生成虚拟贴图的详细技术,只需要知道现在的虚拟贴图不是简单的从磁盘中加载,而是通过程序自动生成的虚拟贴图。

我们假设将超大地形分割成多个sector。为了方便计算我们把10km换成8192m,假设一个sector是512m*512m,那么8912m*8192m就是16*16个sector组成。假设每个sector支持12种画刷,每个画刷是1024*1024的贴图。这样每个sector需要3张mask贴图,每个mask贴图的分辨率为512*512。这样恰好1m对应1024*1024个像素刚好符合1cm/10pixel的要求。我们算一下需要多少的内存存储地形的贴图,一张贴图占4个字节,一张1024*1024的画刷刚好是4M。地形画刷需要4*12*16*16=12288M,算上mipmap为16380M。256张512*512的mask贴图为256M,一共是16392M,大约是16G。因为视距的要求是0.1~10000m,也就是说可以从地形的一边看到另一边(人眼真实的视距也可以达到这个距离,当然需要晴天),假设FOV为90度,大概每一帧需要4G的内存用来存储地形画刷。一个地形的基本贴图就吃掉了4G内存,3A大作也是不允许的。这就是为什么需要虚拟贴图技术来解决贴图问题了。

传统的虚拟贴图技术需要feedback,而且需要indirect贴图来索引物理缓存,这不仅浪费性能还浪费存储空间。因为地形系统是位置连续的几何模型,我们只需要根据角色的位置就可以判断贴图的使用情况,因此我个人觉得clipmap更适合地形系统。

我使用一组2048*2048的纹理数组来存储地形纹理,第一张贴图存储2m*2m的范围,这样像素密度可以达到10cm/pixel,第二张贴图存储4m*4m的范围,第三张贴图16m*16m,依此类推,一共需要13张2048*2048的贴图来覆盖8192m*8192m的地形。这大概需要消耗208m的内存空间。很明显这就是clipmap的基本原理,距离角色近的地形像素密度高,越远像素密度越低。

接下来我们会根据角色的位置来动态渲染这12张贴图,为什么是12张贴图,因为最粗糙的那层是常量,不需要每帧都渲染。上面我们说了将地形分割成多个sector,每个sector使用12种画刷。我们需要确定每张贴图覆盖了哪几个sector,取出这些画刷将tile渲染到贴图上。为此我将每个sector再次划分成多个block,每个block是1m*1m,这样我们可以根据block的位置以及贴图覆盖的地形尺寸计算出覆盖了哪几个sector以及每个sector占贴图的比例。这里还有一个问题,比如第12层贴图,它覆盖了4分之1的地形,它需要768张1024*1024张贴图,算上mipmap以及mask贴图,大概需要4G的内存。为了渲染动态虚拟贴图,需要加载这么大的内存这是不能接受的,因此我使用四叉树来管理地形系统。

根据secotr进行四叉树划分,一共是5层四叉树,叶子节点中存储的是1024*1024分辨率的画刷贴图,上层节点存储的是512*512分辨率的贴图,依次类推,这样存储是合理的,外层的贴图应该使用分辨率低的画刷来渲染。算下渲染12层贴图需要的画刷占内存大概是264M,这个占用还是很理想的。

除了基本的画刷,静态和动态的decal也可以渲染到贴图上。这样就可以支持脚印,破坏等渲染效果。最后总结一下这套方案实现的要点:

1.使用clipmap动态渲染虚拟纹理

2.将场景划分成多个sector,每个sector划分成多个block

3.使用四叉树管理加载的数据,这里存储的数据可以扩展存储植被系统

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值