67.GPU影响因素之顶点和片元

67.性能优化-GPU-影响因素-顶点和片元


67.1 知识点

顶点和片元的基本概念

顶点

顶点一般指模型的几何数据,是组成三角形网格的点。
一个 3D 模型实际上就是由很多三角形拼接而成的,而三角形的角就是顶点。

作用:
是网格的框架点,决定了模型的形状。

着色器阶段:
一般会在着色器中的顶点着色器中进行处理和计算。

顶点着色器主要任务:

  1. 将模型空间的顶点转换到裁剪空间、屏幕空间。
  2. 把需要的数据(UV、法线、颜色等)传递给片元阶段。

片元

片元一般指光栅化阶段产生的、候选的像素点。
当三角形被投影到屏幕后,会覆盖一片像素区域。每个像素位置对应一个片元,GPU 会为它准备一份数据(位置、UV、颜色等)。

作用:
决定屏幕上每个像素的最终颜色。

着色器阶段:
一般会在着色器中的片元着色器中进行处理和计算。

片元着色器主要任务:

  1. 计算像素颜色(光照、材质、纹理采样)。
  2. 执行深度测试、混合、透明处理。
  3. 最终写入帧缓冲,形成屏幕像素。

通俗理解

  • 顶点:就像建房子的”钢筋骨架”。
  • 片元:就是把框架之间的”砖块”一块块填上。

GPU 渲染时:先有骨架(顶点),再填满砖块(片元),最后变成完整画面。

为什么顶点和片元会影响性能

顶点方面

由于顶点数据需要进行计算,以下因素会影响性能开销:

  1. 模型的顶点数越多,计算量越大
    • 高顶点数模型,如未优化的高模、过密网格。
    • 复杂骨骼蒙皮,需要大量骨骼权重计算。
  2. 复杂的顶点着色器逻辑会放大开销
    比如顶点动画(流体波动、噪声扰动、形变等)。

片元方面

由于片元数据需要进行计算,以下因素会影响性能开销:

  1. 分辨率和覆盖率
    片元数直接与屏幕分辨率和绘制面积成正比。
    • 屏幕分辨率越高,片元数就越多,计算消耗就越大。
    • 全屏效果(后处理、屏幕空间特效)通常直接消耗片元性能。
  2. 过度绘制(OverDraw)
    一个像素被多个物体反复覆盖计算。
  3. 高开销片元运算
    复杂的片元着色器逻辑(多层纹理采样、分支、循环、PBR、阴影采样、SSR、体积雾、全屏后处理)非常吃性能。

顶点和片元的优化思路

顶点优化

顶点的主要优化思路就是从本质上减少顶点以及顶点相关的计算。

1. 降低顶点数

  • LOD:根据距离切换不同精度的模型。
  • 网格简化:减少不必要的顶点。
  • 优化远距离对象:使用 Impostor(替身)技术,包括:
    • Billboard(广告牌)
    • 多角度烘焙(在球面或半球面上采样多个角度,把结果打包到一张大纹理图集)
    • Octahedral Impostor(八面体编码,把球面角度映射到 2D 纹理,通过一种高效编码方式存储多角度外观)

2. 蒙皮优化
减少骨骼数量、减少顶点权重、合并骨骼等。

3. 顶点动画
把复杂的程序形变改为 VAT(顶点动画纹理),能贴图查表就别每帧算噪声。

VAT(Vertex Animation Texture,顶点动画纹理):把复杂的顶点动画(顶点位置/法线随时间变化)预先烘焙进贴图里,在运行时通过 Shader 从贴图中查表来驱动顶点,而不是实时在 CPU 或 GPU 上做骨骼/物理计算。

4. 顶点着色器输出精简
减少 v2f 里插值数(TEXCOORD 通道),避免为片元传一堆用不到的数据。

5. 顶点着色器精度和数学

  • 移动端着色器中数值类型尽量用 half
  • 避免大量 sin / cos / pow
  • 能自己写计算过程,就别调用自带的一些高开销函数,比如:pow(x, 2.0)x * x
  • 把复杂函数结果预计算在纹理里,运行时只采样。

6. 合批处理
使用各批处理技术,减少 DrawCall。

7. 剔除先于变换
使用遮挡剔除、视锥剔除,减少要处理的内容。

片元优化

片元的主要优化思路就是从本质上减少片元以及片元相关的计算。

1. 降低分辨率
动态分辨率、注视点渲染等。

2. 降低片元工作量

  • 尽量减少纹理采样次数与层数(合并贴图通道、使用贴图图集)。
  • 片元着色器中减少循环/分支语法的使用。
  • 把复杂函数结果预计算在纹理里,运行时只采样。
  • 减少 OverDraw。

3. 减少全屏 Pass

  • 屏幕后处理中,能半分辨率就半分辨率。
  • 将多种屏幕后处理效果合并在一个 Pass 中处理。

4. 避免 Early-Z(提前深度测试)失效
比如透明测试就会导致其失效。

5. Shader 分支收敛
尽量不要使用 if / else 语法,可以用一些函数替代。

// 原始分支写法
if (mask > 0.5) color = a; else color = b;

// 用插值函数替代
color = lerp(b, a, step(0.5, mask));

6. 光照和阴影
降低光照和阴影质量,光照能用逐顶点就别用逐片元。

7. 合理使用 Mipmap 功能

注意事项

在开发时注意这些优化点,可以减少性能问题的发生。
当发生性能问题时,先定位问题再针对性解决问题,结合性能分析窗口、帧调试窗口来分析定位问题,不要凭感觉。


67.2 知识点代码

Lesson67_性能优化_GPU_影响因素_片元和顶点.cs

public class Lesson67_性能优化_GPU_影响因素_片元和顶点
{
    #region 知识点一 顶点和片元的基本概念

    //顶点和片元如果单独理解

    #region 顶点

    //一般指模型的几何数据,是组成三角形网格的点
    //一个 3D 模型实际上就是由很多三角形拼接而成的,而三角形的角就是顶点

    //作用:
    //是网格的框架点,决定了模型的形状

    //着色器阶段:
    //一般会在着色器中的 顶点着色器 中进行处理和计算

    //顶点着色器 主要任务
    //1.将模型空间的顶点转换到裁剪空间、屏幕空间
    //2.把需要的数据(UV、法线、颜色等)传递给片元阶段

    #endregion

    #region 片元

    //一般指光栅化阶段产生的、候选的像素点
    //当三角形被投影到屏幕后,会覆盖一片像素区域
    //每个像素位置对应一个片元,GPU 会为它准备一份数据(位置、UV、颜色等)

    //作用:
    //决定屏幕上每个像素的最终颜色

    //着色器阶段:
    //一般会在着色器中的 片元着色器 中进行处理和计算

    //主要任务
    //1.计算像素颜色(光照、材质、纹理采样)
    //2.执行深度测试、混合、透明处理
    //3.最终写入帧缓冲,形成屏幕像素

    #endregion

    //说人话
    //顶点:就像建房子的"钢筋骨架"。
    //片元:就是把框架之间的"砖块"一块块填上
    //GPU渲染时:
    //先有骨架(顶点)
    //再填满砖块(片元)
    //最后变成完整画面

    #endregion

    #region 知识点二 为什么顶点和片元会影响性能

    //顶点:
    //由于顶点数据需要进行计算
    //因此以下因素会影响性能开销
    //1.模型的顶点数越多,计算量越大
    //  1-1.高顶点数模型,如未优化的高模、过密网格
    //  1-2.复杂骨骼蒙皮,需要大量骨骼权重计算
    //2.复杂的顶点着色器逻辑会放大开销
    //  比如顶点动画(流体波动、噪声扰动、形变等等)

    //片元:
    //由于片元数据需要进行计算
    //因此以下因素会影响性能开销
    //1.分辨率和覆盖率
    //  片元数直接与屏幕分辨率和绘制面积成正比
    //  1-1.屏幕分辨率越高,片元数就越多,那么计算消耗就越大
    //  1-2.全屏效果(后处理、屏幕空间特效)通常直接消耗片元性能
    //2.过度绘制(Overdraw)
    //  一个像素被多个物体反复覆盖计算
    //3.高开销片元运算
    //  复杂的片元着色器逻辑(多层纹理采样、分支、循环、PBR、阴影采样、SSR、体积雾、全屏后处理)
    //  非常吃性能

    #endregion

    #region 知识点三 顶点和片元的优化思路

    //顶点的主要优化思路就是
    //从本质上减少顶点以及顶点相关的计算
    //1.降低顶点数
    //  1-1.LOD
    //  1-2.网格简化
    //  1-3.优化远距离对象(用Impostor(替身)技术)
    //      Billboard(广告牌)
    //      多角度烘焙(在球面或半球面上采样多个角度,把结果打包到一张大纹理图集)
    //      Octahedral Impostor(八面体编码,把球面角度映射到 2D 纹理,通过一种高效编码方式存储多角度外观)
    //2.蒙皮优化
    //  减少骨骼数量、减少顶点权重、合并骨骼等
    //3.顶点动画
    //  把复杂的程序形变改为VAT(顶点动画纹理)
    //  能贴图查表就别每帧算噪声
    //  VAT(顶点动画纹理):
    //  把复杂的顶点动画(顶点位置/法线随时间变化)预先烘焙进贴图里
    //  在运行时通过 Shader 从贴图中查表来驱动顶点
    //  而不是实时在 CPU 或 GPU 上做骨骼/物理计算
    //4.顶点着色器输出精简
    //  减少 v2f 里插值数(TEXCOORD 通道),避免为片元传一堆用不到的数据
    //5.顶点着色器精度和数学
    //  移动端着色器中数值类型尽量用 half
    //  避免大量 sin/cos/pow
    //  能自己写计算过程,就别调用自带的一些高开销函数,比如:pow(x,2.0) → x*x
    //  把复杂函数结果预计算在纹理里,运行时只采样
    //6.合批处理
    //  使用各批处理技术,减少DrawCall
    //7.剔除先于变换
    //  使用遮挡剔除、视锥剔除,减少要处理的内容
    //等等

    //片元的主要优化思路就是
    //从本质上减少片元以及片元相关的计算
    //1.降低分辨率
    //  动态分辨率、注视点渲染等
    //2.降低片元工作量
    //  尽量减少纹理采样次数与层数(合并贴图通道、使用贴图图集)
    //  片元着色器中减少循环/分支语法的使用
    //  把复杂函数结果预计算在纹理里,运行时只采样
    //  减少OverDraw
    //3.减少全屏Pass
    //  屏幕后处理中,能半分辨率就半分辨率
    //  将多种屏幕后处理效果合并在一个Pass中处理
    //4.避免 Early-Z (提前深度测试)失效
    //  比如透明测试就会导致其失效
    //5.Shader 分支收敛
    //  尽量不要使用if/else语法,可以用一些函数替代
    //  比如
    //  if (mask > 0.5) color = a; else color = b;
    //  用插值函数替代
    //  color = lerp(b, a, step(0.5, mask))
    //6.光照和阴影
    //  降低光照和阴影质量,光照能用逐顶点就别用逐片元
    //7.合理使用Mipmap功能
    //等等

    #endregion

    #region 注意事项

    //在开发时注意这些优化点
    //可以减少性能问题的发生
    //当发生性能问题时先定位问题再针对性解决问题
    //结合性能分析窗口、帧调试窗口来分析定位问题,不要凭感觉

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏