All

Unreal Landscape Edit Layers 支持覆盖混合

问题来源:

 
 

Unreal 4.24 新加了层编辑的功能,这个功能的好处就是在编辑器内,你可以对地表做分层编辑,最后混合成最终的纹理,进入到游戏内使用,使得编辑器编辑的时候有更多的自由度。
 

官方文档:

https://docs.unrealengine.com/zh-CN/Engine/Landscape/Layers/index.html

 
 

这个功能带来的一个核心方便点就是层与层之间的混合问题。

 
 

比如

Landscape Layer B

Landscape Layer A

如果将这两层按照Alpha 1:1 混合的结果是这样:

最终的输出就是不同层的颜色比例混合叠加得到的效果。

 
 

这里我们采用的材质球就是基础的只连basecolor,不同的颜色对应的不同的材质层。

 
 

这再结合使用Houdini的时候有一个好处就是,如果我们将Houdini的生成结果输出到单独的一层,这样的情况下,每次Houdini的重算结果也就只会覆盖这一层。

这样就实现了Houdini生成数据和手动修改数据的分离。

 
 

但是还存在的一个比较大的问题就是,层与层之间的混合在默认情况下,都是根据权重来获得混合结果的。

 
 

比如:

我们来修改层与层之间的混合比例,会得到不一样的效果。

这时候结果如下:

 
 

这样带来的问题就是,无论是Houdini的输出结果,还是原来的手动结果,都会影响最终结果。

 
 

这边存在的一个大问题就是,很多时候,我输出的Houdini结果,是想要对手动结果的修改,而不是混合。

比如上面 Landscape Layer B 是Houdini对手动结果的修改,而没有改动的地方就是黑色的,想要呈现的就是默认的手动修改的部分。

但是采用权重混合的方式是无法实现的,我们这里想要的就是上层结果覆盖下层结果。

 
 

直接想要上层结果覆盖下层结果,目前的实现方案有三种:

 
 

  1. 材质球混合方式的修改

     
     

    见这篇文档,按照这个范例来实现

    https://www.worldofleveldesign.com/categories/ue4/landscape-layers-02-painting.php

     
     

  2. 改变输出策略

     
     

    手动修改层最终不显示,Houdini生成层最终的输出是混合了手动修改层的结果的。

    比如上面的Layer关系如下,最终只展示Houdini生成的结果,手动修改的结果不进入游戏运行时的贴图的生成运算。这个运算是Houdini实现的,混合到了houdini的输出结果里面。

 
 

  1. 改引擎,实现覆盖层的策略。

     
     

    后续我们来实现这个功能。

 
 

解决问题:

 
 

这是我们默认的开启 Landscape Layer 后的地形编辑界面。

 
 

首先我们要理解这边的材质层混合和地形层混合的实现逻辑。

地形层混合只在编辑器内实现,最终输出结果是每一层材质层输出一张贴图。

材质层混合是在游戏运行时,根据用户的自定义使用的材质球来得到混合的结果。

 
 

默认的引擎实现逻辑:

对于每一个地形层的所有材质层,按照逻辑混合(这边的逻辑默认就是加权和,如果勾选了Subtractive Blend,那就是加权减法),混合的结果生成最终的材质层贴图,这个贴图就是用于游戏内的材质球的。

 
 

这也就理解了为什么原来的引擎默认是没有层覆盖的实现的。因为要实现地形层之间的覆盖,那么就存在上层地形层的材质层,去影响下层地形层的各个材质层的结果。运算复杂度从N直接提升到了N^2。这个就是当前的实现思路。

 
 

这里我们实现了两个功能:

 
 

  1. 增加了不同地形层同材质层之间的混合逻辑

     
     

    原来默认就是 Add 和 Sub,我们来加一个 Mul。

    这个的实现比较简单,只要follow原来的框架即可实现

     
     

    界面上我们实现三个复选框的互斥实现,默认情况下是Add。

     
     

    核心实现则是在 LandscapeLayerPS 里面,这边的修改如下,主函数里面支持三种混合模式,原来是加减,这边就多实现一种乘法即可。

     
     

    剩下的工作就是完善传入的数据,使得界面上的选择可以传入到这个pixel shader里面即可。

     
     

     
     

  2. 增加了不同地形层之间的覆盖逻辑

     
     

    这边的实现则是会脱离原来的实现框架,核心就是对于每一层 Cover Landscape Layer,我们都会去修改每一层材质层的已有的混合结果。

     
     

    界面上,我们提供了这个 landscape layer 是否是 cover 层的选框,对于每一层你都可以选中或者不选中。

    特殊的是 Landscape Spline 层,这一层默认就是 Cover 层,不可修改。

 
 

实现的核心就是 ALandscape::RegenerateLayersWeightmaps 函数里面,

遍历每一层 landscape layer:

首先会生成每一层材质层的贴图效果;

然后将当前材质层结果叠加到混合的当前材质层的结果里面;

最后处理混合,每一层的结果加进去,权重合起来,最后完结以后结果除以权重。

 
 

现在要实现叠加,则是对于每一 cover landscape layer 里面的材质层,都会遍历已有的混合好的所有的材质层,将当前的结果直接写到这些混合好的结果里面。

 
 

配合的 LandscapeLayerPS 里面的实现如下,这里还是复用了原来的主函数,添加了一种模式专门用来处理这种混合。

 
 

 
 

实现结果:

 
 

https://youtu.be/iuavy7l-W04

 
 

注意事项:

  1. Cover 层 不支持半透明
  2. Cover 层 不处理高度图

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

Leave a Reply

Your email address will not be published. Required fields are marked *