64.性能优化-GPU-影响因素-填充率
64.1 知识点
填充率的基本概念
填充率(Fill Rate)是 GPU 的一个性能指标,是最经典的衡量图形处理器片元阶段吞吐能力的指标之一。
它表示 GPU 在单位时间内能处理(写入)的像素数量,一般用 像素/秒 来衡量(GPixel/s = 十亿像素/秒,MPixel/s = 百万像素/秒)。
相当于填充率决定了每帧能处理多少个像素。
桌面端举例:
假设 RTX4090 GPU 的理论填充率为 450 GPixel/s = 4500 亿像素/s。
一个 60FPS 的游戏,每帧该 GPU 理论上能处理 4500亿 / 60 = 75 亿像素,即每帧可以处理 75 亿个片元。
如果是一个 4K 显示器(3840 x 2160 ≈ 829 万个像素),每个像素只处理一次的话,理论上 RTX4090 可以每帧处理 4K 画面 75亿 / 829万 ≈ 905 次。
移动端举例:
一般高端移动设备的 GPU 填充率在 20 ~ 40 GPixel/s = 200 ~ 400 亿像素/s。
一个 60FPS 的游戏,每帧理论上能处理 200 ~ 400亿 / 60 = 3.33 ~ 6.66 亿像素,即每帧可以处理 3.33 ~ 6.66 亿个片元。
同样 4K 分辨率下,每个像素只处理一次的话,高端移动设备 GPU 每帧处理 4K 画面 3.33 ~ 6.66亿 / 829万 ≈ 40 ~ 80 次。
说人话:
GPU 填充率就是 GPU 每秒能画多少个像素。
为什么填充率会影响性能
屏幕上每个像素都可能需要执行片元着色器、纹理采样、混合写入等操作,这些工作就是在消耗填充率。
如果把 GPU 想象成一个喷漆机器:
- 屏幕分辨率越高,需要喷的点就越多。
- 特效越复杂(模糊、透明、Bloom 等),每个点需要喷好几层。
- 当喷漆速度赶不上需求,就会产生性能问题。
造成性能瓶颈的原因
1. 过高的分辨率
| 名称 | 分辨率 | 像素总数 |
|---|---|---|
| 720P | 1280 x 720 | 92 万多 |
| 1080P | 1920 x 1080 | 207 万多 |
| 2K | 2560 x 1440 | 369 万多 |
| 3K | 2880 x 1620 | 466 万多 |
| 4K | 3840 x 2160 | 829 万多 |
| 8K | 7680 x 4320 | 3318 万多 |
随着分辨率的增加,GPU 每帧要处理的像素(片元)会指数增加,大幅消耗填充率。
2. 全屏特效或后处理效果
在游戏开发中使用屏幕后处理效果,比如边缘检测、Bloom、运动模糊、高斯模糊、全局雾效、景深(DOF)等,它们会对每个像素进行多次采样和计算,大幅消耗填充率。
3. 多重采样抗锯齿(MSAA)
4x MSAA 相当于每个像素算 4 次,填充率需求翻倍。
- 普通渲染:1 像素 = 1 个采样点(像素中心)
4x MSAA:1 像素 = 4 个采样点,判断覆盖率,最后合成一个像素颜色
4. 透明/半透明物体
每一层都要计算片元,实际填充量成倍增加。
对于不透明物体来说,可以通过深度写入丢弃大量遮挡的片元,只用算一次。
但对于透明/半透明物体来说,必须逐层混合,每个片元需要重复计算多次。
5. 多 Pass Shader
每个 Pass 都会单独进行计算,Pass 中会重算片元(像素)。
假设一个物体表面有 1000 个可见片元:
- 1 个 Pass 带来 1000 次片元着色计算
- 3 个 Pass 带来 3000 次片元着色计算
相当于在同一像素上多次覆盖绘制。
总结:
填充率始终有上限。当单位时间内处理的像素(片元)数量增加,就会消耗填充率。当达到一定瓶颈,就可能给 GPU 带来压力。
一般增加压力的情况为:分辨率高、屏幕后处理多、半透明多、多 Pass Shader、抗锯齿等。一切会增加片元计算次数的行为都会增加 GPU 开销。
关于填充率的优化思路
了解了填充率影响性能的原理,优化思路就很容易得到了。
降低要处理的像素(片元)数量
1. 降低分辨率
动态分辨率(Dynamic Resolution Scaling)
在 GPU 压力大时,降低渲染分辨率,然后再放大到屏幕分辨率输出。
在 GPU 空闲时,提高渲染分辨率,获得更清晰的画面。
目标是保持稳定帧率。URP 项目中有动态分辨率功能开关。注视点渲染(Foveated Rendering)
人眼的视觉分辨率,中央注视点区域最清晰,周边区域分辨率敏感度低。
在中央区域渲染高分辨率,在边缘区域渲染低分辨率,从而减少像素处理量。
一般 VR 项目中会使用,VR 设备会提供对应功能,通过设备 API 开启。降低项目分辨率
基于目标设备,合理设定项目目标分辨率。
2. 减少或优化屏幕后处理效果的使用
在 1/2 或 1/4 分辨率下渲染后处理,或直接不使用。
3. 降低抗锯齿采样次数或关闭4x MSAA → 2x 或关闭。
减少单个像素(片元)计算量
- 控制 Shader Pass 数量
能合并的效果放在一个 Pass,避免片元被重复算。 - 减少半透明的使用
减少层数,必要时用透明测试(AlphaTest)。 - 合理使用光照模式
少用逐像素实时光照。 - 减少纹理采样次数
合并贴图、使用 Mipmap。
避免无效像素(片元)计算
- 减少 OverDraw
- 优化 UI 系统
减少叠层,避免全屏大半透明面板。合并图集减少 DrawCall。 - 剔除不可见对象
用 Occlusion Culling 和视锥剔除。
64.2 知识点代码
Lesson64_性能优化_GPU_影响因素_填充率.cs
public class Lesson64_性能优化_GPU_影响因素_填充率
{
#region 知识点一 填充率的基本概念
//填充率(Fill Rate)
//是GPU的一个性能指标,是最经典的衡量图形处理器片元阶段吞吐能力的指标之一
//表示 GPU 在单位时间内能处理(写入)的像素数量
//一般用 像素/秒 (Pixels per Second,GPixel/s = 十亿像素/秒,MPixel/s = 百万像素每秒) 来衡量
//相当于填充率决定了每帧能处理多少个像素
//假设 RTX4090 GPU的理论填充率为 450 Gpixel/s = 4500 亿像素/s
//一个60FPS的游戏,每帧该 GPU 理论上能处理 4500亿/60 = 75亿像素
//即 每帧可以处理 75亿 个片元
//如果是一个4K显示器 3840 × 2160 ≈ 829 万个像素
//每个像素只处理一次的话
//理论上来说,RTX4090可以每帧处理4K画面 75亿/829万 ≈ 905次
//而一般的高端移动设备的GPU填充率 一般是 20 ~ 40 Gpixel/s = 200 ~ 400 亿像素/s
//那一个60FPS的游戏,每帧该 GPU 理论上能处理 200 ~ 400亿/60 = 3.33 ~ 6.66亿像素
//即 每帧可以处理 3.33 ~ 6.66亿个片元
//如果是一个4K显示器 3840 × 2160 ≈ 829 万个像素
//每个像素只处理一次的话
//理论上来说,高端移动设备的GPU可以每帧处理4K画面 3.33 ~ 6.66亿/829万 ≈ 40 ~ 80次
//说人话:
//GPU填充率就是GPU每秒能画多少个像素
#endregion
#region 知识点二 为什么填充率会影响性能
//屏幕上每个像素都可能需要执行片元着色器、纹理采样、混合写入等操作
//这些工作就是在消耗填充率
//如果我们把 GPU 想象成一个喷漆机器
//屏幕分辨率越高,需要喷的点就越多
//特效越复杂(模糊、透明、Bloom 等),每个点需要喷好几层
//当喷漆速度赶不上需求,就会产生性能问题
//造成性能瓶颈的原因
//1.过高的分辨率
//名称 分辨率 像素总数
//720P 1280x720 92万多
//1080P 1920*1080 207万多
//2K 2560*1440 369万多
//3K 2880*1620 466万多
//4K 3840*2160 829万多
//8K 7680*4320 3318万多
//随着分辨率的增加,GPU每帧要处理的像素(片元)会指数增加
//会大幅消耗填充率
//2.全屏特效或后处理效果
//如果我们在游戏开发中使用屏幕后处理效果
//比如边缘检测、Bloom、运动模糊、高斯模糊、全局雾效、景深(DOF)等等效果
//它们会对每个像素进行多次采样和计算,会大幅消耗填充率
//3.多重采样抗锯齿(MSAA)
//4×MSAA 相当于每个像素算4次,填充率需求翻倍
//普通渲染:1 像素 = 1 个采样点(像素中心)
//4×MSAA:1 像素 = 4 个采样点,判断覆盖率,最后合成一个像素颜色
//4.透明/半透明物体
//每一层都要计算片元,实际填充量成倍增加
//对于不透明物体来说,可以通过深度写入丢弃大量遮挡的片元,只用算一次
//但是对于透明/半透明物体来说,必须逐层混合,每个片元需要重复计算多次
//5.多Pass Shader
//每个Pass都会单独进行计算,Pass中会重算片元(像素)
//假设一个物体表面有 1000 个可见片元
//1 个 Pass 带来 1000 次片元着色计算
//3 个 Pass 带来 3000 次片元着色计算
//相当于在同一像素上多次覆盖绘制
//等等
//说人话:
//填充率始终有上限
//当单位时间内处理的像素(片元)数量增加,就会消耗填充率
//当达到一定瓶颈,就可能会给GPU带来压力
//一般增加压力的情况为:
//分辨率高、屏幕后处理多、半透明多、多Pass Shader 、抗锯齿 等
//一切会增加片元计算次数的行为都增加GPU开销
#endregion
#region 知识点三 关于填充率的优化思路
//了解了填充率影响性能的原理,那么优化思路就很容易得到了
//1.降低要处理的像素(片元)数量
// 1-1.降低分辨率
// 1-1-1:动态分辨率(Dynamic Resolution Scaling)
// 基本原理:
// 在 GPU 压力大时,降低渲染分辨率,然后再放大到屏幕分辨率输出
// 在 GPU 空闲时,提高渲染分辨率,获得更清晰的画面
// 目标是保持 稳定帧率
// URP项目中有动态分辨率功能开关
// 1-1-2:注视点渲染(Foveated Rendering)
// 基本原理:
// 人眼的视觉分辨率,中央注视点区域最清晰,周边区域分辨率敏感度低
// 在中央区域渲染高分辨率,在边缘区域渲染低分辨率,从而减少像素处理量
// 一般VR项目中会使用
// 一般VR设备会提供对应功能,通过设备API开启
// 1-1-3:降低项目分辨率
// 基于目标设备,合理设定项目目标分辨率
// 1-2.减少或优化屏幕后处理效果的使用
// 在 1/2 或 1/4 分辨率下渲染,或直接不使用
// 1-3.降低抗锯齿采样次数或关闭
// 4×MSAA → 2× 或关闭
//2.减少单个像素(片元)计算量
// 2-1.控制Shader Pass数量
// 能合并的效果放在一个 Pass,避免片元被重复算
// 2-2.减少半透明的使用
// 减少层数,必要时用 透明测试(AlphaTest)
// 2-3.合理使用光照模式
// 少用逐像素实时光照
// 2-4.减少纹理采样次数
// 合并贴图、使用 Mipmap
//3.避免无效像素(片元)计算
// 3-1.减少OverDraw
// 3-2.优化UI系统
// 减少叠层,避免全屏大半透明面板
// 合并图集减少 DrawCall
// 3-3.剔除不可见对象
// 用 Occlusion Culling 和视锥剔除
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com