zoukankan      html  css  js  c++  java
  • 引擎设计跟踪(九.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的骨骼信息导出和渲染集成.

  • 相关阅读:
    【Codechef】Chef and Bike(二维多项式插值)
    USACO 完结的一些感想
    USACO 6.5 Checker Challenge
    USACO 6.5 The Clocks
    USACO 6.5 Betsy's Tour (插头dp)
    USACO 6.5 Closed Fences
    USACO 6.4 Electric Fences
    USACO 6.5 All Latin Squares
    USACO 6.4 The Primes
    USACO 6.4 Wisconsin Squares
  • 原文地址:https://www.cnblogs.com/crazii/p/3085449.html
Copyright © 2011-2022 走看看