地形纹理拼接混合实现更多的地形细节

把多个地形纹理合并成图集,渲染时采样对应索引混合,可以做到减少带宽消耗的同时实现丰富的地形纹理混合细节。

Image

其实这是GPU Pro2上详细分享的老地形技术了,实施起来也没太大问题,但值得提防的地方如下:

  1. 自定义Mipmap级别。
  2. 纹理拼接Padding。
  3. 权重绘制方式更变。

自定义Mipmap级别是Opengl白皮书中给出的计算公式,实际上Unity论坛也给出了具体计算公式:

float mip_map_level(in float2 texture_coordinate) // in texel units
{
  float2  dx_vtc  = ddx(texture_coordinate);
  float2  dy_vtc  = ddy(texture_coordinate);
  float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
  return 0.5 * log2(delta_max_sqr);
}

输入是 texel uint,即每块瓦片纹理的尺寸 * 顶点输入uv。

另外,使用该函数算出来的mipmap和硬件自己算出来的mipmap级别有差别,使用该公式计算出来的级别,mip0覆盖的区域比原本的要少,导致地形看上去会比较模糊,在最后添加一个mipmap偏移值Bias可以解决这问题,但是也不能偏移太大,否则mip0会覆盖原本mip1应该占有的区域,造成高频采样噪音。

纹理拼接Padding解决方式比较简单,把原纹理uv缩放并且Clamp采样uv为0-1即可,然后渲染到RT,即可在边缘填充Padding,然后地形渲染时再注意缩放偏移采样。

纹理拼接可以直接在Photoshop中进行,下采样生成mipmap链时滤波器用Box或Kris都行。

最后值得一提的时地图权重保存方式,Pro上的地图混合是连续的,也就是只会相邻地图块混合,但是我们更希望任意两个地形混合,因此需要单独存一个地形纹理索引图,并且滤波模式为点过滤(防止插值),因此没办法和权重图放在一张图里了,因为权重图必须有插值。

最后是性能,实际上如果没有在带宽上获得收益,它会比直接采样原地形贴图来得更慢,原因是因为TileMap采样产生了大量的Texture CacheMiss。

但是当采样纹理数成为了带宽瓶颈,特别是移动端,这技术还是很值得引入的。

© - 2024 · 月光下的旅行。 禁止转载