当前位置:   article > 正文

UE4 实时渲染原理&优化策略笔记_ue4 pbr源码分析

ue4 pbr源码分析

目录

Rendering Before

几何体渲染

光栅化和GBuffer

渲染和纹理

像素着色器和材质

反射

静态光照和静态阴影

动态光照和动态阴影

雾和半透明

后期处理

[实时渲染补充内容]

LOD

贴花Decals

次表面散射补充


(PS:官方大佬Sjoerd de Jong <深入实时渲染>课程的笔记总结,大佬对渲染的原理解释很到位,只有了解原理才能理解为啥这样设置就可以优化性能,才能在实战中举一反三

保证干货满满,建议看完视频后再来,或者结合视频食用...

附上B站教程链接:https://www.bilibili.com/video/BV1KE411r76i?from=search&seid=4460059173728126740

Rendering Before

  • GPU要渲染什么,是由CPU进行通知、决定的。首先,CPU必须要知道场景中一切对象的位置,这是场景中一切可呈现物体的基本属性。同时,CPU要负责计算相关逻辑和变换(空间方面),包括但不限于动画、模型和对象的位置、物理效果、AI、对象的生成与销毁、对象的出现与消失、隐藏与取消隐藏等。

  • 渲染遮挡(剔除)优化要点

     

 

  • 设置距离剔除(下图为Actor设置,植被工具中也有CullDistance选项控制)

     

  • 设置预计算可视性体积,需要编译光照

     

  • 命令stat initViews查看预计算cost

  • 命令stat engine查看渲染三角形数目

 

几何体渲染

  • 相同属性的多面体会调用一次drawcall,同一几何体的不同材质会多次调用

  • basePass负责几何体渲染,gpu逐次调用drawcall渲染并缓存到Gbuffer用于后续处理

  • 查看命令:stat RHI,drawcall调用次数(2000-3000合理,>5000太高)

  • 光照会影响drawcall的调用次数

  • drawcall次数对性能的影响甚至高于多面体模型三角形的个数(高模影响),每次调用都会获取下次渲染信息,调用间隔和传输损耗对影响很大,这意味着过多复杂的材质可能比高精度模型的渲染开销更大

  • RenderDoc插件用于截帧,观察渲染流程:secene列表下每一次都是一次drawcall调用,时钟标记可以看到耗时,依次找出场景中drawcall最耗时的Actor。右边可以预览Gbuffer缓存的内容

  • 静态网格体和下属的组件都会逐个调用drawcall, 减少drawcall次数的两个方法:

    1、合并模型

    2、使用LOD优化

    • 合并或使用少量更大的模型而非大量小型模型

       

      • 大模型减少drawcall调用,但是会带来其他问题:如碰撞检测(CPU计算),遮挡,光照贴图会更复杂

      • 折中策略:使用模块化工作流,即小模型导入,场景搭建中对小模型适度合并,一般远处的模型群需要合并,具体合并策略:

         

        • 同一区域广泛使用(Count)的面数少(Tris)且材质类型相同且合并后面数适中(SumTris)的模型最佳,面数可以使用统计功能筛选:

          window - statistic - primitive stats

           

      • 合并模型来优化drawcall的收益取决于项目的实际帧率需求,权衡时间和收益,否则没有必要过多考虑模型合并的问题

      • 除了合并模型,第二个方面是使用LOD:随着距离变远模型边数降低(按等级50%衰减),占用额外内存(空间换时间),但是不影响drawcall次数。HLOD(分层LOD)是个高级版本,对一组模型按距离同时优化面数和drawcall次数(同组的模型只调用单个模型的drawcall次数,典型例子是植被系统!)

        • 启用:World Settings -> LODSystem -> Enable Hierarchical LODSystem

        • 可视化:window - Hierarchacal LOD

        • 室外场景往往需要进行距离剔除的同时设置HLOD

     

  • Vertex Shaders(顶点着色器)着色器通常高效且并行运算(super optimized),顶点着色器工作于渲染流程的开始阶段

    • 转换局部坐标到世界坐标

    • 处理顶点的绘制和上色

    • 可以用于世界场景偏移,材质节点中的worldPositionOffset,这种偏移只是视觉上的效果,并不是真的位置偏移,如物理和碰撞盒位置不变(因为是CPU计算的),这一点的典型应用场景:

      • 布料、旗帜等摆动

      • 水材质波动效果

      • 植物随风摆动效果

    • 禁用远距离世界坐标偏移!其他顶点着色器优化策略:

       

 

光栅化和GBuffer

  • 光栅化(Rasterizing):将渲染信息映射到一个像素网格图像,光栅化过程随着drawcall的逐次调用执行

  • 过度着色:一个像素点只会同时用于显示一个多边形,而由于硬件原因像素着色器每次按2*2个像素进行着色,这会导致实际着色范围要大于本应渲染的区域

    • 可视化:视窗里viewmode - optimizeViewModes - Quad Overdraw

       

      • 可以看到距离越远的物体渲染越慢,因为会有更多的多边形覆盖更小的像素区域(多边形的像素密度增加了),导致过度着色严重

      • 关于过度着色的具体策略:

         

      • 再次提到LOD:除了减少多边形数量,也会优化过度着色

      • 过度着色在前向渲染中影响较大,延迟渲染中影响不大,因此一般也不需太关注

  • Gbuffer概念:引擎的每一帧渲染都会输出不同的images,缓存到Gbuffer,之后的处理都是用Gbuffer中的图像

    • RenderDoc中能直观预览RGBA通道对应的图像:

      R:世界法线贴图(GbufferA)&金属色(GbufferB) G:高光 B:粗糙度

    • 自定义深度:用单独的渲染目标或者说GBuffer缓存模型,然后用于特效等(轮廓特效)

      • 视口 - 高分辨率截图high resulotion screenshot - use custom depth as mask

 

渲染和纹理

  • textures在导入时会被压缩,不同平台不同,PC使用BC(DXTC),压缩纹理是因为内存和带宽限制,不压缩大小差距巨大,纹理太多或太大会导致渲染卡顿(传输延迟)

  • NoramalMap使用BC5压缩,只保留R/G通道(蓝色的可以计算出来),如果导入的纹理设置不对需要修改

  • 带alpha通道的texture使用BC3, 不带alpha的使用BC1, 禁用压缩的话可以选择RGBA8

     

  • 渐进纹理(MipMaps):纹理随远距离使用更低分辨率的纹理(2次幂衰减),这项技术用于解决噪点问题

     

     

    • window - shadercode - HLSL code可以查看当前材质节点的shader源码

    • 材质编辑依赖引擎大量的shader模板,切换材质域或blendmode导致可用参数变化,本质是切换了shader模板;可以创建自己的shader代码加入项目或插件;每次模板会生成不同用途的着色器版本(材质细节面板的Usage)

  • 像素着色器对性能的影响非常大,分辨率越高材质越复杂影响就越大。如果想概括导致渲染变慢的原因,通常这四个方面:drawcall调用次数,像素着色器,半透明,动态阴影导致了几乎所有的性能问题。

    • 像素着色器复杂度可视化:视窗viewmode - optimization viewmodes- shader complexity (Alt + 8)

  • UE4的材质基于PBR,所有模型材质和着色都是建立在相同的PBR系统上

  • 材质的纹理采样有数量限制:

     

 

静态光照和静态阴影

  • 静态光照预先计算并存储到光照贴图lightmap

  • 高效但会占用内存,无法动态调整,常用于全局光照烘焙

  • 光照贴图依赖UV布局,因此有UV空间上限限制

  • 光照贴图与底色贴图直接相乘,附加在顶层,类似一种自发光

    uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

  • 全局光照设置选项:worldsetting - lightmass

    • 烘焙后的光照贴图在lightMass面板的光照贴图属性组下

    • lightmass时一个独立的渲染器,支持网络分布式渲染

    • lightmass烘焙关联设置:

      1、确保场景中的所有模型的UV通道贴图正常(导入时选项:生成uv lightmap)

      2、光照构建质量;3、lightmass面板参数;

      4、Lightmass Importance Volume(体积内的光照质量更高)

  • 间接光照质量:静态光照解决动态模型光照变化的方法,通过ILC存储光照网格点信息,当达到一个网格点时叠加光照到移动模型身上,光照就会发生变化

    • 可视化:show - vasualize - volume lighting samples (需要光照烘焙后可视)

    • 在可移动是模型actor细节面板Indirect Lighting Cache属性设置质量级别

  • 静态光照优化策略:

    uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

    • 可视化:Viewmode - OptimizationViewmodes - Lightmap Desity

      展示光照UV贴图,用于发现异常扭曲,红色为异常,可以在静态模型的细节面板

      lighting - overriden light map res 调大或调小(动态修改无需重编)

 

动态光照和动态阴影

  • 四种动态阴影

    • 常规阴影:设定为可移动类型的actor,实时阴影,高对比度而且非常锐利,以至于阴影成像经常过渡

    • 固定光源阴影:设定为固定类型的actor,混合使用全局静态光照烘培的阴影和动态阴影,由于混合了静态会软化成像,阴影效果更加柔和,不会太锐利 (注:静态类型无阴影)

    • 级联阴影贴图CSM:用于室外大型场景的动态阴影过渡,在远距离阴影渐进消失,随摄像机距离变远逐级替换低分辨率阴影贴图。只能用于定向光源,细节面板可以控制级联层数,一种兼容性能的折中方案

    • 距离场阴影:CSM的折中方案在室外远距离渐进消失阴影,远距离无法投射阴影仍然比较突兀。相比CSM,距离场更适用于长距离动态阴影方案,不够精确,但性能损耗很低

  • 点光源与动态阴影:类似反射球捕获,点光源在球形遮罩内计算光源(边缘渐进衰减),当多个点光源范围重叠时会重复计算导致额外开销

  • 动态光源本身性能损耗很小,导致性能问题的不是光照而是动态阴影,因为渲染阴影需要光源到所有几何体的距离信息。阴影由像素着色器完成,所以像素越多开销越大。因为光源离摄像机越近涉及到光源渲染的像素越多,所以开销也越大,因此尽量缩小光源半径并且避免重叠

  • 动态阴影优化策略

    • 不需要的阴影就关闭

    • 多面体面数在几何体渲染时本身影响不大,但是会影响阴影从而影响性能

    • 在室外远距离使用距离场阴影优化

    • 在距离足够远时直接关闭光源和阴影

    • 尽量缩小光源半径并且避免重叠

 

雾和半透明

  • 半透明是ue中影响性能最大的因素之一,延迟渲染中半透明比较困难,被推迟到渲染最后阶段进行

  • 表面材质尽量使用蒙版混合模式代替半透明混合模式,如果使用半透明尽量设置shading model成无光照,如果非要半透明,则lighting mode设置成表面前向着色

  • 两种距离雾:大气雾指数级高度雾

     

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

 

后期处理

渲染末尾阶段使用Gbuffer再度计算产生特效,如泛光light bloom,光束light shaft,景深&背景模糊blur,运动模糊motion blur,颜色分级LUT&颜色校正,曝光explosure

uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

 

[实时渲染补充内容]

LOD

  • LOD根据物体与摄像机的距离来设置模型多边形的数量,远离摄像机时自动降低分辨率级别来优化性能

  • LOD从0开始,表示原始最高分辨率,屏幕中所占大小比例表示距离远近

  • 模型mesh的细节面板可以手动设置LOD或外部导入模型LOD,也可以使用UE4的LOD组功能自动设置(推荐),设置分组后可查看各级LOD的具体参数,如该级别LOD的屏幕比例阈值

    uploading.4e448015.gif转存失败重新上传取消uploading.4e448015.gif转存失败重新上传取消

  • 确保AutoComputeLODDistance开启,左上角可实时预览LOD参数

  • 室外场景可同时使用LOD和剔除距离

  • HLOD是一种LOD进化版本,不再对单个模型设置,而是通过生成集群和生成代理对一组Actor设置LOD,代理模型就是组合Actor之后的简易模型代替一组模型,从而极大降低多边形

     

贴花Decals

  • 可以投射在静态网格体或骨骼网格体表面的材质。可以用于血迹弹孔涂鸦高亮等效果。

  • 从 模式(Modes) 面板添加 "延迟贴花(Deferred Decal)"Actor。然后创建材质域为 延迟贴花的新材质。再将该材质应用给贴花Actor。注意轴向投射距离,靠近混合,过远淡出

  • 混合模式Mask,同时使用法线贴图和不透明蒙版产生立体贴花效果

  • 多层贴花使用sort order控制叠加顺序

 

次表面散射补充

  • 次表面散射(Sub-Surface-Scattering)简称3S,用来描述光线穿过透明/半透明表面时发生散射,光从表面进入物体经过内部散射,然后又通过物体表面的其他顶点出射的光线传递过程。

  • 常应用于蜡烛,大理石,玉石以及皮肤材质

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/91555
推荐阅读
相关标签
  

闽ICP备14008679号