学习在UE中使用RVT(RuntimeVirtualTexture)将物体与地形混合过渡

本文介绍了如何在虚幻引擎中利用RuntimeVirtualTexture技术解决物体与地形之间的硬接缝问题。通过启用虚拟纹理支持、创建RVT资源、设置RuntimeVirtualTextureVolume、修改地形和石头材质,以及基于地形高度进行材质混合,实现了平滑的过渡效果。最终,通过调整混合系数,根据与地形的距离实现自然的融合过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

当物体放在地形上并与地形有穿插时,其交界处通常会看到硬接缝。在以前,使用RenderTargets是一个解决方案:将地形等信息渲染到贴图上,其他物体就可以采样这张贴图了,随后根据接近地形的程度,来与渲染的贴图进行不同程度的混合。

在当前的虚幻版本中有了RuntimeVirtualTexture(运行时虚拟纹理),可以取代之前的RenderTargets。(关于它和RenderTargets方式的比较,在这里有讨论,可以参考)。在解决这个物体与地形混合过渡的问题上,RVT的操作和RenderTargets类似,而在步骤上更为简洁。但是最为重要的区别是,它的底层使用了 VirtualTexture(虚拟纹理) 技术,本文末将观察这项技术的使用。

本篇的步骤主要参考了教程How to Blend Objects with Your Landscape - UE4 Runtime Virtual Texturing (RVT) Tutorial - YouTube,不过使用了更简单的资源做测试,算是一个简化。

测试场景准备

我在创建工程时使用了“初学者内容包”。
随意创建一个地形并添加了些随意的噪声。创建一个地形材质时我使用了 T_Ground_Gravel_DT_Ground_Gravel_N 作为基础色贴图与法线贴图。
然后在场景中放入一个石头模型SM_Rock

当前,可以看到石头与地形之间有明显的接缝:
在这里插入图片描述

0. 启用 Virtual Texture

项目设置 =》 引擎-渲染 =》启用虚拟纹理支持
在这里插入图片描述
(启用后需要重启UE)

1. 创建RVT资源

在内容浏览器中右键 材质和纹理 =》运行时虚拟纹理。
在这里插入图片描述
接下来需要两个RVT,一个针对于地形的高度vt_height,一个针对于地形的材质vt_mat
在这里插入图片描述
对于vt_height,选择“场景高度”作为其 虚拟纹理内容
在这里插入图片描述
而对于vt_mat,其 虚拟纹理内容 则留作默认的“底色、法线、粗糙度、高光度”。但是其尺寸可能需要调高一些:
在这里插入图片描述

2. 在场景中创建RVT的Volume

接下来需要在场景中放置RuntimeVirtualTextureVolume,可以从放置面板中搜索此Actor然后拖入场景中。
在这里插入图片描述
然后设置其对应的RVT资源:
在这里插入图片描述
RuntimeVirtualTextureVolume用来指定渲染VT的位置与范围,可以手动指定范围,也可以自动与场景中的地形对齐:选择场景中的地形然后点击“设置边界”。
在这里插入图片描述
由于vt_mat也需要一个这样的Volume,所以可以复制当前Volume,然后设置其对应的RVT:
在这里插入图片描述

3. 在地形材质中指定渲染RVT

在地形材质中使用Runtime Virtual Texture Output节点来将数据写入RVT:
在这里插入图片描述
基本上,就是将原本输出给最终结果的数据,也同时输出给了Runtime Virtual Texture Output节点。
不过有些需要做些处理:

  • 对于“法线”,需要将其从切线空间转换为世界空间
  • 对于“高度”,需要对原本从“绝对世界位置”节点中获取的三维向量,取其RGB中的B(因为虚幻中XYZ中的Z代表向上的高度)

4. 指定地形输出的RVT资源

选择地形Actor,指定将vt_heightvt_mat填入其虚拟纹理的数组中。填入后就可看到RVT渲染出了内容:
在这里插入图片描述

5. 在石头材质中采样RVT

Runtime Virtual Texture Sample节点可以在材质中对RVT进行采样。
在石头材质中添加一个此节点,然后设置其RVT资源为vt_mat,这个RVT中将有地形的底色和法线等。
在这里插入图片描述
随后,将其数据连入石头材质的最终输出:
在这里插入图片描述
需要注意的是:

  • 由于之前在地形材质中,写入RVT中的法线是世界空间的,而这里石头材质的输出需要的是切线空间,所以需要添加节点将世界空间转换为切线空间

随后,可以在场景中看到现在石头材质的表现:
在这里插入图片描述
可以注意到,其与地形交界处已经没有明显接缝(不过还是能看出接缝,因为UV的拉伸度有突变)。

当然,目前的效果不是最终想要的,因为期望是其只在接近地形的位置处才趋近于地形材质。因此,接下来就需要使用地形高度来决定混合程度了。

6. 在石头材质中采样地形高度RVT并进行材质混合

为了方便混合,我将采样的地形材质通过一个Make Material Attributes封装为一个整体:
在这里插入图片描述
而石头材质原本的输出连到另一个Make Material Attributes节点中:
在这里插入图片描述
接下来,就是通过Blend Material Attributes节点依据高度将二者混合,并输出给最终结果了:(最终输出节点需要勾选“使用材质属性”,这样才能变为一个读取整个Material Attributes的引脚)
在这里插入图片描述
此处的 Alpha 就是混合系数,此时:
A l p h a { = 0 : 采 样 的 地 形 材 质 = 1 : 石 头 原 本 的 材 质 0 ∼ 1 : 由 地 形 到 石 头 过 渡 Alpha \begin{cases} =0 : & 采样的地形材质\\ =1: & 石头原本的材质\\ 0 \sim 1: &由地形到石头过渡 \end{cases} Alpha=0:=1:01:

而这个 Alpha 期望根据与地形高度的距离进行计算。


在先前地形材质中已经设定了将高度输出到RVT中,所以同理在石头材质中再创建一个Runtime Virtual Texture Sample节点,但其RVT资源应设置为vt_height(“虚拟纹理内容”应该也会被自动设置为“场景高度”):
在这里插入图片描述
接着,便可以将当前的位置的高度减去地形高度,获得的与地形的距离记为 d
在这里插入图片描述
对于 d 它期望有如下表现:
d { ⩽ 0 : 采 样 的 地 形 材 质 ⩾ 过 渡 范 围 : 石 头 原 本 的 材 质 0 ∼ 过 渡 范 围 : 由 地 形 到 石 头 过 渡 d \begin{cases} \leqslant 0 : & 采样的地形材质\\ \geqslant 过渡范围: & 石头原本的材质\\ 0 \sim 过渡范围: &由地形到石头过渡 \end{cases} d0::0:
为了将 dAlpha,需要做两件事:

  1. 将 “0 ~ 过渡范围” 变换为 “0 ~ 1” ,为此需要将 d 除以“过渡范围”。
  2. 将 0 ~ 1 范围之外的值 clamp 到 0 ~ 1 。

我将这个“过渡范围”提取为参数range,然后连接下面的节点:
在这里插入图片描述
最终节点:(隐藏了左侧石头原本的材质节点)
在这里插入图片描述

效果

range取值为“20”的情况下,效果如下:
在这里插入图片描述
其和不使用的效果还是有很大差别:
在这里插入图片描述
可以随意拖动感受效果:
在这里插入图片描述

至此,效果已经实现。

不过作为延伸,也可以稍微观察一下虚拟纹理技术:

*观察虚拟纹理技术

启用UE的RenderDoc插件后,使用它来截一帧:
在这里插入图片描述
随后,可以在左侧找到绘制石头所用的DrawCall,我这里是:
Scene -> BasePass -> BasePass -> TestRockMat SM_Rock。
在这次DrawCall的右侧的输出纹理中,可以看到石头将其本身的法线和颜色等信息输出到了GBuffer上:
在这里插入图片描述
接下来就是虚拟纹理技术有趣的地方了。
按照本篇操作的步骤,逻辑上是:先把地形的材质等信息渲染到了一张大纹理中,随后石头渲染时将会采样这张地形的大纹理并进行混合。然而实际上,这张大纹理从没有真正存在过,它是虚拟的。
如果观察这次DrawCall的输入纹理,你不会找到地形的大纹理,你只能找到:
在这里插入图片描述
可以看到它由一些图块组成。而这些图块如何得到,渲染时如何采样,便是虚拟纹理系统所考虑的问题了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值