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

UE 渲染改造:交叉渐变效果 Part.1 前言

[复制链接]
发表于 2022-5-18 18:34 | 显示全部楼层 |阅读模式
Part.2: UE 渲染改造:交叉渐变效果 Part.2 实现渲染管线中保留一帧的功能
Part.3: UE 渲染改造:交叉渐变效果 Part.3 自定义材质节点,向材质蓝图暴露截取的保留帧
Part.4: TBA
本系列文章将同时发表在个人博客页面:
<hr/>使用 Unreal Engine 5 进行实现和演示。效果预览:

UE 渲染改造:交叉渐变效果
https://www.zhihu.com/video/1506817346149236736
完整视频可以移步 Bilibili:
这篇文章所介绍的技术,在原理层面比较简单,但如果需要将此技术优雅地植入到引擎现有的庞杂逻辑中,则需要对引擎本身的构成有着一定程度上的了解,因此这篇文章希望能够通过一个具体案例,让初次接触相关方向的读者熟悉 UE 渲染器中各种模块的架构。
由于 UE 本身非常庞大,想要充分理解其体系中的全部实现细节几乎是不可能的。同时,网上虽然存在的大量自底向上,展示类关系图和源码分析的文章,但是在没有案例和动机的情况下,这些文章的理解难度同样也非常高,一些文章甚至不如直接亲自阅读源码和打断点看调用堆栈的主动学习方法有效(毕竟 C++ 本身就是给人阅读的)。因此,这里我通过一个具体案例,自顶向下地,按需引入 UE 中一些模块的原理,并且展现出思考解决方法的过程,将各种实现方案的优雅性、性能、效果罗列出来并进行取舍,并附上一些延伸阅读材料。当通过案例大概掌握各个模块的宏观架构之后,再去自底向上地细致了解其实现细节才是学习复杂软件系统的最佳途径。
如果想直接了解实现过程,可以忽略所有引用块内的文本(样式同此段文本),或者直接找到文章中的代码块即可。
<hr/>


Microsoft PowerPoint 中的渐变效果

不知道大家有没有发现,游戏的过场动画中,两个机位之间直接切换(即 Hard Cut)比较多,而用花里胡哨的渐变效果的却几乎没有。我认为,一是在游戏一直在效仿的电影行业当中,直接切换的应用比例就非常高,只有在切换大场景/时间线这种需要让用户意识到蒙太奇的存在时才需要做一些渐变切换效果,例如交叉渐变或者擦除渐变(著名的例子包括星战系列、夺宝奇兵,以及一些好莱坞的老电影);二是,渐变效果注定会在渐变的过程中,让两个镜头的画面同时存在于屏幕上,在实时渲染中无疑是压力很大的——渲染器需要在渐变这段时间同时生成两个不同角度机位的画面,甚至这两个机位分别属于完全不同的两个场景。



神秘海域中的实时渐变切换

但在游戏的艺术化进程中,我们偶尔也需要通过交叉渐变来满足导演的表达要求。大名鼎鼎的《神秘海域4》中就存在着大量的渐变手法来突出场景的时空转换。正好最近在做自己的小项目时,也遇到了类似的要求,也大概列举了一下几种实现起来比较简单的解决方案:

  • 最暴力的解决方案:同时渲染两个相机呗。但是在 UE 中,如果我想渲染到 RT,需要使用 Scene Capture 2D,然后后处理材质读入两个 RT 做混合,但我又想在渐变完了之后将视角重新交还到角色逻辑上做正常的玩家视角,还得考虑到万一目标视角就是玩家可以立刻控制的呢?这种乱糟糟的逻辑很难保证框架的优雅性,因此放弃。
  • 修改 UE 自带的多 View 渲染机制。但简单的阅读代码就可以发现,UE 做出来多 View 机制其实就是针对本地分屏来设计的,在 Base Pass 中,不同的 View 都渲染到同一组 Scene Texture 组合,通过 Viewport 来控制分屏中每一个用户视角的渲染范围。这显然不能直接用在渐变中。


当然,我们可以借助着分屏的渲染机制,让渐变前后画面分别对应在 Scene Texture 的不同位置上,但通过改变每一个 View 渲染时的变换矩阵保留原始横纵比(类似于将正常画面挤压到画面左半边/右半边)。在后处理过后增加一个 Pass,将左右半边合成回渐变。这种实现方法可以说是在能够保证渐变前后视角都是动态的情况下,最省性能的做法了(因为两个视角共享一个场景,同时输出的像素数量没有变化),但其在渐变时,将前后视角的渲染分辨率分别在横向上减半,此时再试图去引入升采样机制来弥补分辨率损失的话,可能一片文章真的就写不下了……

  • 录制视频(FMV)。此种实现方法被大量用在游戏的过场动画中,其拥有最好的画面质量,同时几乎不耗费性能。当然缺点也显而易见,其不能适用于动态视角切换,同时视频的分辨率、码率、文件大小也都会产生问题。
  • 在转换之前“截一帧”,转换时用这一帧静态图和转换后的动态视角实现渐变效果。此种方法不足之处在于渐变前的视角在渐变时变成了静态图,容易穿帮,但其在性能、内存占用和画质上都有不错的表现,非常适用于视角移动不太剧烈的场景中。同时,如果将截的这张图作为自定义节点暴露给材质蓝图的话,借助着 UE 强大的材质编辑能力,使用后处理材质可以完全将渐变效果交给美术来调节。本文中介绍的既是这种实现方案
有些人可能会问了,保留一帧有啥可大动干戈改造渲染器的,Reddit 上一搜净是这种实现方法。不过大多数方法仍然是通过使用 Scene Capture 2D 来捕捉场景画面到一个 RT 资源上,进而被后处理材质所使用。Scene Capture 2D 在捕捉场景时,由于和场景视角(View)本身都不是一个 View Family,其性能开销比多 View 渲染还要大很多,虽然只保留一帧,但这一帧显然会造成不小的卡顿,无法作为正式项目的解决方法,因此需要更改渲染器,让渲染器能够保留特定的一帧,并且提供给后处理材质。

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-11-16 09:01 , Processed in 0.094349 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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