64.GPU影响因素之填充率

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 想象成一个喷漆机器:

  1. 屏幕分辨率越高,需要喷的点就越多。
  2. 特效越复杂(模糊、透明、Bloom 等),每个点需要喷好几层。
  3. 当喷漆速度赶不上需求,就会产生性能问题。

造成性能瓶颈的原因

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 MSAA2x 或关闭。

减少单个像素(片元)计算量

  1. 控制 Shader Pass 数量
    能合并的效果放在一个 Pass,避免片元被重复算。
  2. 减少半透明的使用
    减少层数,必要时用透明测试(AlphaTest)。
  3. 合理使用光照模式
    少用逐像素实时光照。
  4. 减少纹理采样次数
    合并贴图、使用 Mipmap。

避免无效像素(片元)计算

  1. 减少 OverDraw
  2. 优化 UI 系统
    减少叠层,避免全屏大半透明面板。合并图集减少 DrawCall。
  3. 剔除不可见对象
    用 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

×

喜欢就点赞,疼爱就打赏