赞
踩
当物体放在地形上并与地形有穿插时,其交界处通常会看到硬接缝。在以前,使用RenderTargets是一个解决方案:将地形等信息渲染到贴图上,其他物体就可以采样这张贴图了,随后根据接近地形的程度,来与渲染的贴图进行不同程度的混合。
在当前的虚幻版本中有了RuntimeVirtualTexture(运行时虚拟纹理),可以取代之前的RenderTargets。(关于它和RenderTargets方式的比较,在这里有讨论,可以参考)。在解决这个物体与地形混合过渡的问题上,RVT的操作和RenderTargets类似,而在步骤上更为简洁。但是最为重要的区别是,它的底层使用了 VirtualTexture(虚拟纹理) 技术,本文末将观察这项技术的使用。
本篇的步骤主要参考了教程How to Blend Objects with Your Landscape - UE4 Runtime Virtual Texturing (RVT) Tutorial - YouTube,不过使用了更简单的资源做测试,算是一个简化。
我在创建工程时使用了“初学者内容包”。
随意创建一个地形并添加了些随意的噪声。创建一个地形材质时我使用了 T_Ground_Gravel_D 和 T_Ground_Gravel_N 作为基础色贴图与法线贴图。
然后在场景中放入一个石头模型SM_Rock。
当前,可以看到石头与地形之间有明显的接缝:

项目设置 =》 引擎-渲染 =》启用虚拟纹理支持

(启用后需要重启UE)
在内容浏览器中右键 材质和纹理 =》运行时虚拟纹理。

接下来需要两个RVT,一个针对于地形的高度vt_height,一个针对于地形的材质vt_mat

对于vt_height,选择“场景高度”作为其 虚拟纹理内容。

而对于vt_mat,其 虚拟纹理内容 则留作默认的“底色、法线、粗糙度、高光度”。但是其尺寸可能需要调高一些:

接下来需要在场景中放置RuntimeVirtualTextureVolume,可以从放置面板中搜索此Actor然后拖入场景中。

然后设置其对应的RVT资源:

RuntimeVirtualTextureVolume用来指定渲染VT的位置与范围,可以手动指定范围,也可以自动与场景中的地形对齐:选择场景中的地形然后点击“设置边界”。

由于vt_mat也需要一个这样的Volume,所以可以复制当前Volume,然后设置其对应的RVT:

在地形材质中使用Runtime Virtual Texture Output节点来将数据写入RVT:

基本上,就是将原本输出给最终结果的数据,也同时输出给了Runtime Virtual Texture Output节点。
不过有些需要做些处理:
选择地形Actor,指定将vt_height和vt_mat填入其虚拟纹理的数组中。填入后就可看到RVT渲染出了内容:

Runtime Virtual Texture Sample节点可以在材质中对RVT进行采样。
在石头材质中添加一个此节点,然后设置其RVT资源为vt_mat,这个RVT中将有地形的底色和法线等。

随后,将其数据连入石头材质的最终输出:

需要注意的是:
随后,可以在场景中看到现在石头材质的表现:

可以注意到,其与地形交界处已经没有明显接缝(不过还是能看出接缝,因为UV的拉伸度有突变)。
当然,目前的效果不是最终想要的,因为期望是其只在接近地形的位置处才趋近于地形材质。因此,接下来就需要使用地形高度来决定混合程度了。
为了方便混合,我将采样的地形材质通过一个Make Material Attributes封装为一个整体:

而石头材质原本的输出连到另一个Make Material Attributes节点中:

接下来,就是通过Blend Material Attributes节点依据高度将二者混合,并输出给最终结果了:(最终输出节点需要勾选“使用材质属性”,这样才能变为一个读取整个Material Attributes的引脚)

此处的 Alpha 就是混合系数,此时:
A
l
p
h
a
{
=
0
:
采
样
的
地
形
材
质
=
1
:
石
头
原
本
的
材
质
0
∼
1
:
由
地
形
到
石
头
过
渡
Alpha
而这个 Alpha 期望根据与地形高度的距离进行计算。
在先前地形材质中已经设定了将高度输出到RVT中,所以同理在石头材质中再创建一个Runtime Virtual Texture Sample节点,但其RVT资源应设置为vt_height(“虚拟纹理内容”应该也会被自动设置为“场景高度”):

接着,便可以将当前的位置的高度减去地形高度,获得的与地形的距离记为 d。

对于 d 它期望有如下表现:
d
{
⩽
0
:
采
样
的
地
形
材
质
⩾
过
渡
范
围
:
石
头
原
本
的
材
质
0
∼
过
渡
范
围
:
由
地
形
到
石
头
过
渡
d
为了将 d 变 Alpha,需要做两件事:
我将这个“过渡范围”提取为参数range,然后连接下面的节点:

最终节点:(隐藏了左侧石头原本的材质节点)

在range取值为“20”的情况下,效果如下:

其和不使用的效果还是有很大差别:

可以随意拖动感受效果:

至此,效果已经实现。
不过作为延伸,也可以稍微观察一下虚拟纹理技术:
启用UE的RenderDoc插件后,使用它来截一帧:

随后,可以在左侧找到绘制石头所用的DrawCall,我这里是:
Scene -> BasePass -> BasePass -> TestRockMat SM_Rock。
在这次DrawCall的右侧的输出纹理中,可以看到石头将其本身的法线和颜色等信息输出到了GBuffer上:

接下来就是虚拟纹理技术有趣的地方了。
按照本篇操作的步骤,逻辑上是:先把地形的材质等信息渲染到了一张大纹理中,随后石头渲染时将会采样这张地形的大纹理并进行混合。然而实际上,这张大纹理从没有真正存在过,它是虚拟的。
如果观察这次DrawCall的输入纹理,你不会找到地形的大纹理,你只能找到:

可以看到它由一些图块组成。而这些图块如何得到,渲染时如何采样,便是虚拟纹理系统所考虑的问题了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。