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 MSAA → 2x 或关闭。

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

  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

赏

×

喜欢就点赞,疼爱就打赏