找回密码
 立即注册
查看: 319|回复: 0

Unreal Engine 4 渲染目标(Render Target)教程 之 实现雪地足迹(下)

[复制链接]
发表于 2023-4-12 18:11 | 显示全部楼层 |阅读模式
本文是《Unreal Engine 4 渲染目标(Render Target)教程 之 实现雪地足迹》的第三部分
第一部分请见《Unreal Engine 4 渲染目标(Render Target)教程 之 实现雪地足迹(上)》
第二部分请见《Unreal Engine 4 渲染目标(Render Target)教程 之 实现雪地足迹(中)》
作者|Tommy Tran Jun 3 2018 | 翻译 开发游戏的老王
文章目录



        使用渲染目标足迹的持久化创建持久化缓存回写到scene capture移动Scene Capture非连续地移动Scene Capture移动持久化缓存



使用渲染目标

让我们从颜色混合开始。把上文中的1-x节点和Lerp节点如下图所示连接:


注:你可能好奇为什么我使用一个1-x节点,其实就是翻转一下渲染目标,让计算稍稍简单点。
有足迹的地方地面将会是褐色的,反之是白色的。
接下来,按如下图高亮所示实现顶点置换:


这样,有雪的地方会被提高25个单位;没雪的地方不会被置换,从而实现了足迹效果。
注:我们可以通过DisplacementHeight节点来增减雪的高度。并且DisplacementHeight的值应该是和捕获偏移量(capture offset)相同。把它们设为相同可以使形变更加精确。但有时我们想单独设置它们,因此本文把它设为了独立的参数。
点击Apply并回到主编辑器。在关卡中创建一个BP_Capture的实例并将其位置设为 (0, 0, -2000) 让它置于地下。点击Play,并使用W, A, S,D键移动角色,就可以使雪地形变了。


产生形变了,但是并没有足迹!这是因为每次捕获都会覆盖之前渲染目标之前的内容。我们现在需要实现足迹的持久化。
足迹的持久化

为了使足迹持久化,我们需要另外一个渲染目标作为持久化缓存(persistent buffer),在足迹被覆盖之前把它存储到持久化缓存中。然后再把持久化缓存返回给scene capture。这样我们就得到了两个渲染目标互相写来写去的循环结构,它就是我们实现持久化的方法。


下面,我们先来创建持久化缓存。
创建持久化缓存

RenderTargets文件夹创建一个新的Render Target并命名为RT_Persistent。本教程中,我们无须更改纹理设置。在你自己的项目中,请确保两个渲染目标的分辨率相同。
接下来,我们需要一个材质将之前scene capture内容拷贝到持久化缓存中。打开Materials\M_DrawToPersistent并添加Texture Sample节点。将其纹理设为RT_Capture并如下图连接:


然后点击Apply并打开BP_Capture。首先创建一个动态材质实例(稍后我们再为它传值)。将如下高亮节点添加到Event BeginPlay


Clear Render Target 2D节点的作用是确保每个渲染目标在使用前被清空。
接下来,打开DrawToPersistent函数并添加如下高亮节点:


接下来,将DrawToPersistent函数添加到Event Tick,其目的是确保每一帧都要向持久化缓存中绘制,因为scene capture发生在每一帧。


最后,将持久化缓存添回到渲染目标。
回写到scene capture

点击Compile并打开PP_DepthCheck。然后添加高亮节点,并确保Texture Sample设为 RT_Persistent


现在渲染目标之间可以互相读写了,我们也获得了持久的足迹。点击Apply并关闭材质。点击Play,开始在雪上踩脚印吧!


效果看起来棒棒哒,但此时的效果仅适用于地图上的一个区域,如果角色走出这个区域就没有足迹了。


一种解决办法就是,让scene capture随着角色移动。这就意味着足迹永远回出现在角色所在的区域。
注:随着scene capture的移动,任何其范围之外的区域都会被忽略掉。这就意味着,当我们回到刚才有足迹的地方,它们也会消失。不要着急,在下一个教程中我们会学习如何实现半持久化(semi-persistency)。
移动Scene Capture

你可能觉得我们要做的只是把Capture的XY位置设置为角色的XY位置。但如果你这样做的话,渲染目标就会变得模糊。这是因为我们移动渲染目标的步长小于1个像素。这样一个像素的新位置就会定位在像素之间。于是多个像素对一个像素进行插值,其结果如下:


解决办法是,我们需要非连续地移动移动Scene Capture。我们需要做的就是计算每个像素对应的**实际大小(world size)**然后每次都将Scene Capture移动这个距离。这样每个像素就不会重叠,也就不会有模糊了。
先创建参数存储Scene Capture的位置。地面材质会用这个值计算投影。打开 MPC_Capture添加Vector Parameter并命名为CaptureLocation


接下来,使用新的参数更新地面材质。关闭MPC_Capture 并代开 M_Landscape。如下修改第1部分:


现在,渲染目标就永远被投射到Scene Capture的位置了。点击Apply并关闭材质。
非连续地移动Scene Capture

使用如下公式计算像素的实际大小:
  1. (1/ RenderTargetResolution)* CaptureSize
复制代码
使用如下公式计算新位置的每一个分量:
  1. (floor(Position / PixelWorldSize)+0.5)* PixelWorldSize
复制代码
为了节省时间,笔者为第二个公式创建了一个SnapToPixelWorldSize 宏。打开BP_Capture并打开MoveCapture函数。然后创建如下连接:

上面的代码会计算新的位置并将新旧位置的差存储到MoveOffset中。如果你使用的分辨率不是256×256,请确保你修改了高亮标记的值。
接下来,如下图连接节点:


上述代码会使用计算出的偏移量移动Scene Capture,然后把新的位置存储到MPC_Capture以供地面材质使用。
最后,我们需要每一帧都执行位置更新。关闭函数并在Event TickDrawToPersistent节点的前面添加MoveCapture


移动完Scene Capture,本方案只完成了一半,我们还必须移动持久化缓存。否则就会出现下面奇怪的结果:


移动持久化缓存

要移动持久化缓存,我们需要传入之前计算好的偏移量。打开M_DrawToPersistent并添加如下高亮节点:

上述代码会使用提供的偏移量移动持久化缓存。就像地面材质一样,我们需要翻转X坐标并实施遮罩。点击Apply并关闭材质。
接下来,我们需要传入偏移量。打开BP_Capture并打开DrawToPersistent。然后,添加如下高亮节点:

上述代码会将MoveOffset转换成UV坐标并传入draw material
点击Compile并关闭蓝图。点击Play,无论你跑多远,雪地上的足迹将永远伴随着你!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-1 23:05 , Processed in 0.091575 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表