0. 概述
UE实现了的一些渲染特性:
1. 渲染前准备
游戏线程-渲染线程-GPU线程,同时工作,时间点有偏差。
1.1 第0帧-0ms-游戏线程(CPU)
开始渲染前,要知道参与渲染的物体在什么位置。游戏线程执行所有逻辑计算和物体的交换:动画、模型或物体的位置、物理、AI、生成或销毁、隐藏或显示。
1.2 第1帧-33ms-渲染线程(大部分在CPU)
还需要知道哪些物体应该被渲染在画面中,只渲染可见的内容。
遮挡过程,逐物体而不是逐三角形。
- 距离剔除
- Actor - Rendering - Desired Max Draw Distance:剔除距离
- Cull Distance Volume:距离剔除体积
- 视锥剔除
- 视口 - Show- Advanced - Camera Frustums:开启相机视锥体可见性
- 控制台 - FreezeRendering:冻结当前渲染结果
- 控制台 - ToggleDebugCamera:切换成Debug相机
- 预计算可见性:将可见性结果提前计算好并存储下来,额外内存开销
- Precomputed Visibility Volume
- Build - Build Precompute Static Visibility
- World Settings - Precomputed Visibility
- Show - Visualize - Pre…蓝色方块
- 遮挡剔除
遮挡过程性能提示:
- 设置距离剔除(默认是关闭的,但很容易打开,更适用于室外环境)
- 大于1w个物体会对性能有较大影响
- 大部分情况下CPU是瓶颈,有时候可能GPU
- 遮挡在大型开放世界通常作用比较小(较容易看到更多物体)
- 所有的物体都会被遮挡(粒子也会)
- 大的物体很难被遮挡,因此在GPU渲染上可能需要消耗更多的时间
1.3 第3帧-66ms-几何体渲染(GPU)
1.3.1 Prepass
Prepass/Early Z Pass:找出哪些模型应该先被渲染,避免一些像素重复绘制造成浪费。GPU驱动会在执行像素着色器前检查该点深度,提前跳过不符合条件的像素。
画了水桶没被栏杆遮挡的部分。
1.3.2 Drawcall
Drawcall:渲染时在特定pass中采用的单一处理过程。通常可以理解为绘制拥有相同属性的一组多边形。
切换材质影响性能开销,相同材质的会在一个批次绘制。
Drawcall对性能的影响:
- 对性能影响很大。
- 每次GPU绘制完成后,需要从渲染线程拿新的指令,这里开销大。
- Drawcall数量对性能的影响比三角形数量要大很多。
通过stat RHI命令查看Drawcall统计数据:
- 2000-3000 合理
- >=5000 略高
- >=10000 也许会有性能问题
- 移动端 几百合适
DrawCall相关的性能提示:
- Drawcall数量相比多边形数量对性能的影响更大
- 引擎有一些Drawcall的基础开销
- 为了降低Drawcall,我们可以将模型进行合并(合并模型使用Merge Actors,而不是Actor中的多个Component,那实际上还是分立的模型),但也有副作用:
- 遮挡检测性能更差
- 计算碰撞性能更差
- 占用更多内存
- 一个较为常用的技术Modular Meshes
- 也可以使用Instancing降低Drawcall
- Level Of Detail (LOD)和HLOD
插件开启RenderDoc可以使用工具查看Drawcall等信息
1.3.3 Shader
高效,流水线执行。Vertex Pixel Compute Other
Vertex Shader:
- 将坐标从局部空间->世界空间->投影空间进行转换
- 处理顶点着色
- 应用世界坐标偏移(World Position Offset, WPO)
- 衣服
- 水体表面
- 叶子植被艹随风飘动动画
- 动物动画(鸟起飞)
- 官方顶点动画工具VertexAnimationTool
顶点着色器性能提示:
- 动画越复杂性能越慢
- 顶点越多性能越慢
- 高精度模型最好使用简单的Vertex
- 对远距离的物体禁用顶点动画
UE5新的Nanite。
光栅化:找到三角形内部需要渲染的像素点。因为光栅化会计算周边2x2的像素,存在Overshading,顶点和边的像素计算了多次。
光栅化和Overshading性能提示:
- 多边形越密集,渲染的开销越大
- 从更远处观察物体,多边形的密度会增加
- 使用LOD或远距离剔除
- PixelShader越复杂,Overshading开销越大
- 细长的三角形会造成严重的Overshading
将物体表面信息存储在一系列图像中,称为G-Buffer。可以使用Custom Depth作为Mask输出,可以使用MovieRenderQueue输出。G-Buffer会占用很多内存和带宽,所以数量有限制。
1.3.4 纹理
- 纹理在导入时会被压缩,可以大大减少GPU显存占用
- 不同的平台有不同的压缩方式,Windows上BC算法
- 法向贴图只保留了RG通道,因为归一了
- Shader中对采样纹理的数量有限制
- 纹理的分辨率主要影响的是内存和带宽,而不是着色
- 为了减少锯齿和加快渲染速度,开启Mipmap。大小是原来是1+1/4+1/16…≈1.33
要使用Mipmap,需要纹理的尺寸是2的幂次方,UI贴图可以不需要Mipmap
1.3.5 像素着色器和材质
PixelShader是材质系统的底层实现。Windows使用的HLSL。
PBR:
- Physical Based Rendering
- 使用Specular/Metallic/Roughness来描述一种材质的属性
- PBR是一种统一着色模型,修改参数表现不同材质
- UE中几乎所有的模型都是使用PBR模型进行渲染的:
- 可以达到最快的效率
- 可预测
- 基于G-Buffer的合成工作流限制
材质性能提示:
- 每个材质的纹理采样器有最大数量限制(16),DX11可以使用共享采样器(128)
- 纹理尺寸过大会导致短暂的卡顿(内存导致)
- 像素着色器对性能有非常大的影响,可以优化材质编辑器中的指令数(100~200)
- 屏幕输出的分辨率越大,复杂材质对性能的影响越大
999. Ref
- 【[官方培训]01-实时渲染基础上 | 陈拓 Epic】 https://www.bilibili.com/video/BV1Tt4y1H7kQ
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 cdd@ahucd.cn