对官方教程视频[官方培训]02-实时渲染基础下 | 陈拓 Epic的笔记
没听懂的地方就瞎写
反射
实时渲染中反射是一个非常有挑战的特性
UE中有多种不同的方案,各有各的优势和缺点
反射捕获
屏幕空间反射
平面反射
Lumen
RT Reflection
反射捕获
在指定位置捕获一张Cube Map
需要预计算
快速
不精确
只能捕获一定距离范围内的物体
反射捕获文档
反射捕获的使用方法是在场景中放置reflection capture actor,actor会捕获一张自身位置的cube map,在渲染时会以这张cube map作为光源来计算反射
反射捕获使用的是一张预先计算的立方体贴图,因此运行速度很快,但并不精确,且只有局部的效果,相机离捕获位置越近则越精确
只开启反射捕获的测试,帧率是高了但效果一言难尽:
反射捕获的立方体贴图分辨率可以在项目设置中修改,影响反射效果清晰度:
如果场景中有多个反射捕获且半径较大出现了反射捕获重叠的情况,重叠区域会导致像素进行多次计算,使性能损耗变大
平面反射
并不常见,也不常常使用,仅限在指定平面上
在某些设置下可能会有很大的性能损耗(每帧都会捕获画面)
适合需要精确反射的表面(例如镜子)
平面反射文档
平面反射需要在场景添加Planar Reflection Actor,并包裹需要反射的平面,项目设置中的"全局剪切平面"也需要打开
使用平面反射的地板效果,与反射捕获相比更为准确:
平面反射本质上也是一个摄像机,以平面的视角将几乎整个场景又重新渲染了一次,所以对性能的损耗非常大
屏幕空间反射
默认开启的反射系统
对任何物体都有影响
准确
输出有噪声,性能损耗较大
只反射视野范围内可见的物体
屏幕空间反射文档
屏幕空间反射是引擎中唯一默认激活的反射系统
通过控制台开启或关闭屏幕空间反射:
r.SSR.Quality 0//关闭
r.SSR.Quality 4//开启
后期盒子中也有相关设置:
一个比较明显的问题是屏幕空间反射只能反射我们屏幕里能看到的内容,屏幕看不到的内容不会进行绘制,如下图在屏幕边缘的倒影反射
反射性能提示
如果未经过Cook,反射捕获会在打开关卡时进行,导致加载变慢
反射捕获区域如果有很多重叠,会导致多次着色从而性能变差
反射捕获的分辨率可以在系统设置中调节
天空光为整个关卡提供了低成本的反射捕获
必要时才使用平面反射的实时捕获和SSR
光照
光源类型文档
静态光源 (Static Light)
是指在运行时不能以任何方式改变或移动的光源。它们仅在光照贴图中进行计算,一旦处理完成后,不会再有进一步的性能影响。可移动对象不能和静态光源进行交互,所以静态光源的用处是非常有限的
可移动光源 (Movable Lights)
产生完全动态的光照和阴影,可以改变光源位置、旋转、颜色、衰减、半径等属性,几乎光源的任何属性都可以修改。它们产生的光照不会烘焙到光照贴图中,也不会产生间接光照效果
固定光源(Stationary Lights)
保特固定位置不变的光源,但可以在其他方面进行变更,例如亮度和颜色。这是它们与静态光源的主要不同之处,静态光源无法在游戏时以任何方式进行变更。然而,应该注意的是,在运行时对亮度进行修改仅会影响直接光照。间接(反射)光照由于是通过 Lightmass 进行预计算的,所以不会改变
静态光照和阴景
与反射一样,光照和阴影在实时计算也很困难
部分光照、阴影的计算会在预计算阶段完成,在runtime与实时光照结合
虚幻引擎中有数十种不同的光照和阴影方案
Lightmap(光照贴图)
理解虚幻引擎中的光照贴图
静态光照主要通过Lightmap实现,Lightmap是一张烘焙了光照和阴影的贴图,在计算光照时与BaseColor相乘
Lightmap原理示意图:
在虚幻引擎中使用 Lightmass 工具生成 Lightmap,多张Lightmap 会合并到 atlas 中,可以逐个 mesh 调整 Lightmap 密度
场景中的Lightmap可以在World Setting 中的Lightmass下的light map中查看
贴图的分辨率可以在物体的light map resolution override属性修改,分辨率越高则阴影越清晰
在视口中可以可视化查看场景物体的Lightmap分辨率情况
对于静态光照,不管是移动了光源还是物体,都需要重新构建烘焙光照贴图
Volumetric Lightmap
Lightmass会生成表面光照贴图,用于表现静态对象上的间接光照。但是,动态的对象 (例如角色)也需要一种接受间接光照的方法。这种方法就是在构建时将所有点的预计算光照存储在名为体积光照贴图的空间中,然后在运行时用于动态对象的间接光照的插值。
如下图所示,在空间中记录了一系列的点,这些点上以求谐系数的形式保存了当前这个位置的光照信息,在绘制动态物体时,取靠近物体的点对他们的光照结果进行插值
使用控制台代码显示当前场景中的Volumetric Lightmap采样点:
ShowFlag.VisualizeVolumetricLightmap 1
Lightmass
虚幻引擎使用Lightmass来构建Lightmap
Lightmass 是一个独立程序,由引擎编辑器在烘焙时调用
支持网络分布式渲染
渲染质量可以通过一些选项设置
GPU Lightmass
在UE4.27添加了GPU Lightmass,大大减少了计算、构建和生成复杂场景光照数据所需的时间,其速度可与基于CPU的Lightmass使用Swarm进行分布式构建时的速度相媲美。此外还提供具有交互性的新工作流,可以实时编辑场景、重新计算和重新构建光照,基于CPU的Lightmass系统无法使用此工作流
GPU Lightmass全局光照
静态光照质量总结
可以处理间接和全局光照
真实的阴影效果包括软阴影
光照和阴影的质量取决于Lightmap的分辨率和UV分布
由于UV布局的关系,光照还可能显示出接缝
Lightmap分辨率有上限,巨大的模型可能效果不佳
一旦烘焙完成,在运行时静态的光源和物体无法移动
静态光照性能总结
在编辑器下预先计算,并将信息储存在Lightmap中
计算非常高效,但占用更多内存
需要一定的时间去预计算
每次修改光照和静态物体,需要重新构建光照
模型需要Lightmap UV,因此需要额外的步骤去处理
静态光照性能提示
静态光照总是以完全相同的速度渲染
无论有多少静态光源,烘焙之后的渲染速度是一样的
Lightmap分辨率会影响内存,但不影响帧率
烘焙速度会受以下几点影响
Lightmap分辨率模型
光源数量
烘焙选项
光照影响范围
动态光照和阴影
动态阴影
常规动态阴影
级联阴影
逐对象阴影
距离场阴影
常规动态阴影(阴影非常锐利)
Shadow Acne(阴影失真)
阴影贴图分辨率不足时会导致阴影失真,光源的阴影偏移设置有助于减少这些类型的瑕疵
阴影偏差文档
级联阴影(Cascaded Shadow Maps)
阴影贴图的分辨率低,锯齿严重
视锥体分割
方向光、不同距离
级联阴影贴图文档
传统的阴影贴图方法是将所有的物体全部渲染在一张阴影贴图中,对于近距离的物体,贴图分辨率是不够的,级联阴影对视椎进行分割,使用多张阴影贴图,离相机近的地方使用精细的阴影贴图,远的地方使用粗糙的,既优化了阴影的效果,也保证了渲染的效率
逐对象阴影
针对可移动物体
针对固定光源 (位置固定,颜色、光强可变)
针对单独的每一个物体渲染它的阴影贴图,同时保证了分辨率和贴图的使用率
//教程里只是一句带过,文档里也没找到具体说明
距离场阴影(Distance Field Shadows)
可以生成软阴影,不需要针对模型运行阴影pass
从空间中待着色的点出发,沿着光线方向前进
由于需要直接光照,光源需是固定或可移动光源
只对静态网格体有效,需离线生成Mesh Distance Field(网格体距离场)
(Mesh Distance Field在UE5中默认开启,但在UE4中默认关闭)
同时开启情况下的优先级: 级联阴影 > 距离场阴影 > 传统阴影
运行实时生成Global Distance Field
Ray Marching
距离场阴影文档
其他阴影
Contact Shadow -- 对于小的物体有较好的细节
Capsule Shadow -- 用简化的模型来渲染阴影
阴影性能提示
渲染阴影的性能损耗大,通常需要降低渲染质量来补偿
动态光照不会对大部分的内容产生间接或全局光照
动态光照不会生成“真正的”软阴影,只是通过模拟实现
动态光照在场景中看起来更“真实”,光线非常锐利
动态光照
使用像素着色器计算
点光源用一个球形模型来渲染,在球投影内像素会进行光照渲染
方向光对全屏像素进行渲染
动态光照性能提示
动态光照在延迟渲染中性能损耗相对少
像素越多性能越慢
光源本身并不是问题和损耗的所在,阴影才是,损耗源于像素的着色运算,因此像素越多性速度越慢
光源离相机越近,受影响的像素越多,性能也就越慢
光源半径需要尽可能小,避免重叠
点光源如果有重叠,重叠部分会进行多次着色计算
Lumen和VSM
Lumen是虚幻引擎5全新的全动态全局光照和反射系统,使用了多种光线追踪方法来处理全局光照和反射
VSM是对应的阴影解决方案
UE5创建的工程默认开启了Lumen,如果是从UE4升级的项目需要进行设置:
项目设置中选择动态全局光照方法
项目设置中选择反射方法
项目设置中开启网格距离场
Lumen支持特性
Color bleeding
Soft indirect shadow
Multi-bounce indirect illumination
Emissive materia
Skylight emissive
Color bleeding
Color bleeding使被光照射到的物体表面的颜色会影响周围物体表面的颜色
Soft indirect shadow
Soft indirect shadow(间接软阴影)可以使场景中没有受到直接光照的物体投下阴影,传统方法是使用AO贴图或屏幕空间的AO算法来粗略估算阴影的产生方式,UE5中Lumen完全取代了UE4中的SSAO,消除了实时生成AO贴图的需求,并提供了精确且柔和的阴影
AO: Ambient Occlusion,三维图形渲染中用来表示物体之间相互影响效果的环境光遮蔽贴图,主要用于改善阴影
Multi-bounce indirect illumination
Multi-bounce indirect illumination(多次反弹间接照明)通过追踪前一帧的光照来计算当前帧的光照,这意味着光照结果是当前帧和前几帧混合在一起的结果
r.Lumen.Radiosity 0//关闭间接光照
Lumen原理说明
处理全局光照最常用的方法就是光线追踪,光线追踪通过追踪光线来模拟光线和物体相交时的效果并生成图像,全局光照需要大量的追踪来生成间接漫反射、软阴影和二次反射等
Lumen使用了混合的追踪方法,首先它会追踪屏幕上的光线,但只追踪屏幕上的光线无法覆盖全部场景,所以Lumen还大量使用了硬件加速的光线追踪,为了支持老一些的设备,Lumen还通过有向距离场生成简化的场景来加速追踪,因此也提供了光线追踪的软件方案
另外由于直接采样追踪到的三角形会有巨大的消耗,Lumen通过采样表面缓存的方式来加速计算光照结果,通过Lumen Sence我们可以看到Lumen是如何照亮这个场景的,可以在可视化选项中查看Lumen Sence:
Lumen正是使用这些内容来生成全局光照、阴影和反射的,Lumen scene的内容也会被直接用来计算场景的反射,不再需要在场景里放置反射捕获,一旦在项目中启用了Lumen反射,它也会完全取代屏幕空间反射和光线追踪反射
UE4的屏幕空间反射和光线追踪反射会直接忽略粗糙材质,而在Lumen中能够为粗糙的表面计算出更好的反射结果
半透明
延迟渲染管线难以处理半透明材质
半透明渲染在渲染流程的后半段
使用前向渲染管线渲染半透明物体
半透明是延迟渲染器的弱项之一,也是实时渲染中最大的性能影响因素之一,不仅仅是虚幻引擎,任何延迟渲染引擎都会遇到这个困难
通常会将半透明渲染放在渲染流程中非常靠后的阶段,在前向渲染中渲染透明效果要简单得多,引擎使用的办法就是在前向渲染中完成半透明物体的渲染,然后将结果和延迟渲染的结果进行合并
前向渲染:
每个几何体从顶点着色器到像素着色器,输出到图元缓冲区后,再进行下一个物体的渲染,即一个一个的渲染,场景有多少物体就渲染多少次
优点
1.前向渲染是从头到尾走完一个着色模型,所以对于着色器的支持更好,可以使用更多种类着色器,和更多功能
2.特别适合半透明物体,每个物体的渲染都是单独的,不会出现透明物体渲染错误的情况
缺点
1.无效渲染太多,如前面的物体挡住了后面的物体,被挡住的部分相机看不见,但是依旧被渲染了出来
2.无法支持过多光源,每个物体都会走一遍着色器,每个着色器都会去进行光源的计算,如100个光源100个着色模型,那么光源就会被计算10000次
延迟渲染:
得到深度信息后,对场景里的所有物体一窝蜂一起进行渲染
优点
1.支持多光源,只渲染可见像素不会无效计算
缺点
1.支持的shader种类少
2.延迟渲染储存的信息大,带宽开销高
3.处理半透明物体比较蛋疼
半透明性能提示
渲染半透明材质的对性能影响很大
像素被多层半透明材质覆盖,性能损耗很大
渲染排序也会增加性能的损耗
后期处理
后期处理效果文档
后期处理就是在渲染流程的最未端应用的一个视觉特效,顾名思义这就是它为什么被称为后期处理,后期处理很大程度上也依赖于像素着色器,并且也是利用合成来实现,它通过再度使用G-buffer来计算各种效果
Bloom (泛光)
泛光是真实摄像机的光照瑕疵,它通过再现光源和反射性表面周围的辉光来增加所渲染图像的真实感
DOF (Depth of Field,景深)
景深根据焦点前后的距离为场景应用模糊效果。该效果用于根据深度将观看者的注意力吸引到镜头中的特定主体上。它还可以增加一种美感,使渲染的图像看起来更像照片或胶片
Lensflare (镜头光晕)
镜头光晕效果可模拟在查看明亮物体时由于摄像机镜头缺陷导致的光散射
Vignette (暗角)
暗角效果创建一个无边框窗口,使图像朝边缘淡出
Tonemapping (色调映射)
色调映射功能的目的是将广泛的高动态范围(HDR)颜色映射到显示器能够输出的低动态范围(LDR),可以将色调映射的过程想象成一种模拟胶片对光线的反应的方法
Motion Blur (动态模糊)
动态模糊基于对象运动情况使对象模糊。在摄影与电影中(如一系列帧),动态模糊源于捕获图像之前的对象移动,从而产生可见的模糊效果
Exposure (曝光)
曝光类目包含的属性用于选择要使用的曝光方法类型,以及指定场景在给定时间内应该变得多亮或多暗
自定义的后期处理材质需要把材质域设置为后期处理
实时光线追踪
Ray Tracing(光线追踪)指追踪从摄像机出发的光线在场景中多次反弹的过程,光线的生成和反弹符合物理规律,使得渲染效果非常逼真
从相机发射一条光线交于场景中某一点,将这个点与场景中的光源连线,如果连线被其他物体阻挡,则这个点处于阴影中,如果与某个光源的连线没有被其他物体阻挡,则这个点是被该光源照亮的
如果一条光线射到一个光滑的表面上,可以根据这个光滑表面的法线计算出它的反射光线,再将反射光线所交的点的颜色值赋给这个点
光线追踪文档
性能调试(Profiling)
Stat命令
stat unit
查看不同线程执行的耗时
stat game
查看game线程
stat initviews
查看draw线程
stat gpu
查看gpu线程
使用Ctrl+Shift+,快捷键也可以显示GPU查看器
GPU Visualizer
Unreal Visualizer是一个独立的可执行程序,可以帮助开发者来识别瓶颈用于性能优化,还可以用于收集分析和显示引擎发出的数据,还可以轻松添加用户自身的分析数据
可以从里面活获得各个函数运行的时间、运行的次数、当前帧率、各线程使用情况等信息
Unreal Insight
Frontend session
这俩教程视频里没展开,我也懒得去了解了,相比性能优化还是先弄明白怎么把功能实现比较重要