游戏人生

不积跬步,无以至千里;不积小流,无以成江海。

导航

引擎设计跟踪(九.6) 地形最近更新

1.FastDXT

前两天没事profiling了一下,发现squish的DXT压缩速度很慢,单块压缩速度是解压的10倍...

网上搜了一个用SSE intrinsics优化的DXT压缩库(好像Id soft也在用,或者其员工是原作者),开源的:

http://www.evl.uic.edu/cavern/fastdxt/

适合实时压缩的.不过没有解压功能,解压仍使用squish.

FastDXT确实很快,感觉速度是squish的好几倍,但是不够精确.在某些情况下,会产生错误,比如我的地形混合图,将4个通道压缩到3通道的DXT1,在squish下压缩没有问题,
改用FastDXT以后,混合不对,混合边缘有模糊的黑色的点.

2.地形相关改进

a.数据压缩

之前的数据压缩已经做的差不多了,这次只是简单做下剩余的.
地形的图层数据LayerBuffer(Atlas中的子纹理索引)使用了int8x4的vertex stream,而vertex position中有一个int16的空通道,为了节省内存,所以把它压缩后放到vertex position中了.压缩的前提是Atlas只有4x4的大小,这样一个0-15正好可以解压出两个0-3的索引,一个int16: 0xFFFF正好可以保存4层贴图索引.

这个layer buffer是per-vertex的stream,但是目前使用的时候是per-block的即每个block上的所有vertex的layer data一样,有相当多的浪费,正好借这个机会把它改成per-vertex的.


改完以后发现在编辑的时候不太方便,layer buffer和blend buffer是需要在刷贴图的时候一起编辑的,但是blend map是纹理数据(比如512x512),layerbuffer是顶点数据(比如513x513)两者坐标系不一样导致需要稍微分别处理,不太舒服,
而且打算做geom-morphing,这样这个int16的顶点数据想用来做morphing,所以最后决定将int16的vertex layerbuffer,改为用A4R4G4B4的layermap,这样编辑时处理起来一致了.

但是出现了新的问题,刷纹理的时候有缝, 最后分析是blendmap的DXT1格式,4x4的颜色块精度不够,因为BlockCompress是有颜色压缩和插值的,一个像素的值会影响整个块的颜色,导致跟layer map不匹配(layer map和blendmap的编辑需要做到精确匹配到每一个像素).最后只好把blend map改成A1R5G5B5格式,问题解决.这也同时解决了blendmap用FastDXT压缩出现的错误/不精确问题.


对于一个512x512的tile:

  • 如果不做vertex morphing的话,vertex layer buffer内存全部省去(放入已存在的空通道), 省去1M数据.
  • 因为要做morphing, vertex layer buffer 到layer map 内存省了一半(512K),而blendmap的内存占用翻了两番(DXT1 128K-> RGB555 512K多了384K), 最后每个tile的内存,比以前省128K. 比前者(不做morph)多了896K, 其中512K是等价的顶点morph数据, 另外384K是blendmap调整后的增量.
  • 将顶点数据的水平位置和高度值拆开,分成两个stream,这样水平位置可以在不同tile之间复用和共享,在多tile的时候,每个tile又省了1M数据.这个之前一直没做,拖到现在,渲染的改动不大,但是地形的空间查询改动有点大,因为它用到了顶点流数据.

最后的结果是,使用了geomorphing的情况下, 每个tile的内存,与以前相比, 最大可节约 1M + 128K, 如果是3x3的tiles,节约大概9M内存.

b.geomorphing

vertex position 中保存额外的low LOD height,用于morph的插值.
low LOD height用该LOD级别下的两个邻接点线性插值就可以了,这个高度值跟GPU在低LOD时的顶点插值结果一致.

morph计算全部在GPU端做,需要一个额外shader变量:相机位置, morph参数根据顶点与相机距离,以及顶点的LOD等级等信息计算出来.
目前我是将low LOD height和LOD level压缩到一个int16的通道里面去了(layer buffer转到layer map腾出来的通道). 因为LOD level不会特别大,我这里最大值是4,占用low LOD height的低位,
这样会导致lowLOD height不精确,但是完全可以接受. 最大有4/32767的单位化精度损失,乘以地形实际最大高度,比如512米,最后的影响值是0.0625米.因为这个高度值本身就用来做变形插值,所以肉眼观察不到差别和问题.

c. triplanar map

这个主要是为了解决陡峭地形的贴图拉伸变形.

一个有参考性的paper: http://www.cosc.canterbury.ac.nz/research/reports/HonsReps/2008/hons_0801.pdf

文中提到了triplanar map,虽然没有细讲,但是这是我第一次发现这个概念的地方,至于更深入的paper,可以根据关键字搜搜看.

效果图(http://zeq2.com/lite/forums/viewtopic.php?t=1324&sid=3a0b799c5b1815de8a14c871d14c6158): 
triplanar texture map

这个暂时没有做,计划放后面有机会在做,因为它的效果虽然不错,但是纹理采样次数实在是太多了(x3了)...

3.后续计划

后面会继续做Gizmo helper和骨骼动画:max的骨骼信息导出和渲染集成.

posted on 2013-06-01 21:23  crazii  阅读(693)  评论(0编辑  收藏  举报