地形系统思路来自 ProjectS中的GPU Driven

前言

再来回顾下传统地表材质与我们定好的方案之间的对比:

  • 传统Weight Blend方案:通过纹理 + Mask图实现多纹理混合渲染
    • 每多一张纹理贴图,就要多一份遮罩数据。
    • 由于每点的mask总和为1,所以改变一层需要动到其他所有层的数据,耦合度太高,不方面大规模修改迭代。
    • 编辑器在处理edit layer时,由于需要全局的归一化操作,所以会让上层的layer表现非常奇怪。
    • 随着edit layer的增加,内存和操作延时也会是个问题。
    • 渲染时由于每个地块使用的weightmap各不相同,所以加大了合批处理的难度。
  • Material Id方案:确保每个点只有一种纹理贴图的情况下,通过一张Material Id图控制,最后通过双线性插值混合平滑,这里的材质不是指材质球,而是指一个数据结构,其中包含材质参数,贴图索引以及其他信息
    • 优点是这张MaterialId,它相当于一个间接的索引,每个值表示一张纹理图。8位的单通道materialID图就足以支持超过200种纹理图。它的大小可控,不会随着纹理数量的增加而增加。同时,由于不需要归一化操作,在支持多层edit layer方面也比较简单,保证上层layer覆盖下层即可。
      • 刷地形纹理的时候记录纹理值,例如0,1,2,3。。。然后从materialID图中得到具体的纹理
      • 所有纹理通过Unity的TextureArray进行存储
    • materialID的使用让纹理数量不成问题,但相较于weightmap算法有个明显的缺点,就是边缘过渡比较生硬。为了解决这个问题,可以增加materialID的信息,做双层material混合。可以想象成为抹在蛋糕上的奶油(爆炒。
      • 8位Material Id A + 8位Material Id B + 混合权重 + 8位其他, B会覆盖在A上
    • 如果追求高品质的地表效果,可以在TextureArray加上法线,粗糙度,ao贴图等,通过自定义的Index规则进行索引