All Unreal Engine 4

Unreal Landscape TextureArray 分析

 
 

  • 是否采用了TextureArray

 
 

整个地形虽然在编辑的时候存在多层高度图,但是在运行的时候,heightmap就只有一张在使用,weightmap是多张,在LandscapeComponent这个层面看不出来用的是Texture还是TextureArray,这边用的是逻辑的贴图书组。

 
 

然后我们来看 Landscape 这边的实现

 
 

Alandscape 对象里面,存在这两个对象:

这里的注释很好的解释了这两个纹理数组资源的含义。

CombinedLayersWeightmapAllMaterialLayersResource 存储的是所有层一起混合后的绘制层贴图资源;

CurrentLayersWeightmapAllMaterialLayersResource 存储的是当前层的绘制层贴图资源;

上面的层的含义是地形层,就是多层高度图的层的含义。后续所有的layertexture操作引用到的都是这两个Resources对象。

 
 

这个资源的创建,在ALandscape::InitializeLayersWeightmapResources()里面实现

 
 

也就是说,weightmap层对应的就是一个TextureArray数组,而前面LandscapeComponent里面存的Texture2D指向的就是这个数组内的贴图。

 
 

 
 

 
 

  • LandscapeComponent 控制层数

 
 

强力控制每个LandscapeComponentweightmap最大数量

int32 MaxPaintedLayersPerComponent; // 0 = disabled

 
 

超限直接刷子不管用

 
 

也就是说Unreal保证一个LandscapeComponent所用到的贴图混合层数的时候是在制作的时候实现的,而不是后面程序自动控制。下面是生成LandscapeComponent对应的材质贴图Instance的代码,就是直接拷贝FLandscapeLayerComponentData数据结构里面存储的贴图数量和weightmap

 
 

用这个参数的好处,在制作的时候就控制好了最终每个地形块最多有多少层混合,这样会手动处理好landscapecomponent边界的混合问题。

如果在制作过程中不控制,在渲染的时候强制landscapecomponent最多多少层混合,会导致component边界不连续。具体看下面的测试。

 
 

 
 

实际使用测试


如下图所示,当左边的
Painting Restriction设置为Limit Layer Count的时候,就可以保证每一个LandscapeComponent只刷你设定的MaxPaintedLayersPerComponent值的层数。比如这里MaxPaintedLayersPerComponent=4,因此当你刷第五层的时候,会如右图所示刷不上去,边界处会出现硬边。

 
 

这边的区别在于,Unreal每4层和并为一张mask,比如上图我们控制了每个landscapecomponent最多四层,输入混合mask就如下一张,涉及的贴图也是四张。

如果landscapecomponent达到了五层,涉及了五张贴图,效果如下: