大世界-地形系统(开篇)

转载请注明出处 何文西

 

前言

我们项目是一款45度俯视角的沙盒游戏,场景要求非常大,场景尺寸一般在1024X1024或者2048X2048。在技术上这么大规模的场景一次性加载必定带来效率问题,所以需要考虑到场景切割。项目需求里还要有天气系统,实时的昼夜系统。

 

综上所述会涉及到多个技术要点:

1 地形切割

有很多插件支持Mesh切割和Terrain切割。

如果自己要写切割代码,那么要注意切割后边缘顶点的法线和切线,还有地块之间的接缝问题。

 

2 地表分组

按照地形块分组,可以使用四叉树组织数据。

基于场景编辑器,每个地表元素对应我们resource资源表里的一个ID,例如一棵树,一块石头,一个物件等。

这样只需保存一个资源ID,位置,朝向,缩放,layer等信息。如果使用了光照贴图,还需要保存一下该位置地表元素的光照数据(光照索引和UV)。

地表数据可以保存在XML文件里或者自定义格式的二进制文件里。

考虑到加载效率优先保存为二进制文件。

 

3 光照贴图

使用一张Lightmap显然不合适,一般有2种方法,拆分地形后重新烘培或者切分烘培好的光照图。

注意如果切分光照图,那么场景里物件的光照图索引和UV都需要更新。

 

4 实时光照

这种方式最省心,当然效果不如光照图模式,而且会增加场景里的顶点数和Drawcall。

但是实现实时的昼夜系统最便捷,我们游戏的场景复杂度不是很高,且风格偏卡通,面数自然也不高,相机也是锁视角。

这种方式会优先考虑。

 

5 地块加载

采用九宫格加载最合适,一些3A级的游戏也有采用六边形地块加载模式,这种方式的优点是只需加载周边6个地块。

还可以采取一些缓存优化策略,缓存一定数量的地块,每次加载的地块做一个权重加成,位置也会影响权重加成,需要卸载的时候选择权重最低的。

光照探针是不支持动态加载的。

 

6 地表加载

如果使用了光照贴图,对于动态生成的物件代码里需要指定光照索引和UV。

 

7 动态批处理

如果地块分割尺寸特别大,那么地块区域内的地表元素会非常多,动批时很可能会造成严重的卡顿,而且我们场景里的部分树和石头是可以采集的。

 

posted @ 2018-05-08 15:19  何文西  阅读(...)  评论(...编辑  收藏