一、地形篇
1、地形网格。
AIR引擎的地形设计,是基于四叉树的管理,既然用了四叉树,就有相对应的地块数据,在AIR引擎里面是TerrainBlock。一个地块可以理解成一个网格数据的封装,也是一个Renderable(可渲染物),四叉树中放的就是这些地块的对象。而地块在场景加载的时候,是通过高度图加载的。现阶段地形是行和宽的顶点数必须是一样的,并且一定要是2的N次方加1,这样才能平均划分出NXN个地块。而这里需要注意的是,地块边的顶点不能大于129,因为超过这个数,索引的最大值就超过了16位最大值。
而最关心的地形顶点与索引数据,我在引擎里面是这样实现的,每个地块一个独立的VertexBuffer,所有地块共享一系列的IndexBuffer(为什么这样做,与LOD有关)。VertexBuffer根据地形高度图和一个块的大小配置已经生成好了,而IndexBuffer,是根据地形的大小和可能存在的LOD的情况生成(下面会介绍生成算法)。
2、地形LOD。
地形的LOD是根据地块离眼睛的距离,地块的陡峭程度决定的,如果地块完全是平的,当然取最大层的LOD就行了。
IndexBuffer生成:每个块会有一到四个地相阾块,而它们的LOD值不一定一样,IndexBuffer的生成就是根据这个地块相阾四块的LOD差值和它当前的LOD值生成的,这样也就解决了裂缝的问题。
优化:之前我的做法是在引擎启动的时候,就生成了所有地块可能存在的LOD差值情况下的IndexBuffer,在四层LOD的环境中,生成了300多个IndexBuffer,内存也升高了100M左右。而我在后来的做法中,一开始并不需要生成所有IndexBuffer,而是在渲染过程中根据当时的LOD差值来动态生成,下次再查找的时候,如果已经存在这个IndexBuffer就不用生成了。这样既省了内存,也省了加载时间。
3、地形纹理。
AIR引擎的地块纹理是每个地块最多4张纹理,一张索引纹理,索引纹理是RGBA四个通道决定四张纹理的像素比例。
4、渲染流程。
相机裁剪->计算裁剪后的地块的LOD->地块放入渲染队列->获得当前的IndexBuffer->渲染。