当前位置: 首页 > news >正文

Chapter16 渲染优化技术——Shader入门精要学习笔记

Chapter16 渲染优化技术

  • 一、移动平台的特点
    • 移除隐藏的表面
  • 二、影响性能的因素
    • 造成性能瓶颈的原因
      • CPU
      • GPU
  • 三、Unity中渲染分析工具
    • 1.渲染统计窗口 Rendering Statistics Window
    • 2.性能分析器(Profiler)的渲染区域
    • 3.帧调试器 Frame Debugger
    • 4.其他性能分析工具
  • 四、减少Draw Call的数目
    • 1.动态批处理
    • 2.静态批处理
    • 3.共享材质
    • 4.批处理注意事项
  • 五、减少需要处理的顶点数目
    • 1.优化几何体
    • 2.模型的LOD技术 Level of Detail
    • 3.遮挡剔除技术 Occlusion culling
  • 六、减少需要处理的片元数目
    • 1.控制绘制顺序
    • 2.警惕透明物体
    • 3.减少实时光照和阴影
  • 七、节省带宽
    • 1.减少纹理大小
    • 2.利用分辨率缩放
  • 八、减少技术复杂度
    • 1.Shader 的 LOD 技术
    • 2.代码优化

一、移动平台的特点

  • GPU架构与PC端有很大的不同,移动设备上专注于尽可能使用更小的带宽和功能
  • 需要针对不同的芯片平台,进行更有针对性的优化,尤其是在安卓平台上

移除隐藏的表面

  • 减少overdraw(即一个像素被绘制多次)
  • PowerVR芯片:基于瓦片的延迟渲染 TBDR架构:把所有渲染图元装进一个个瓦片中,再由硬件找到可见的片元,只有可见的片元才会执行片元着色器
  • Adreno(高通)或Mali(ARM):Early-Z或相似的技术,进行低精密度的深度检测,来剔除不需要的片元

二、影响性能的因素

  • 游戏主要需要使用的计算资源:CPU和GPU——互相合作,让游戏可以在预期的帧率分辨率下工作,CPU负责保证帧率,GPU负责分辨率

造成性能瓶颈的原因

CPU

  • 过多的Draw Call —— CPU需要多次改变渲染设置,很耗时
  • 复杂的脚本或者物理模拟

GPU

  • 顶点处理
    • 过多的顶点
    • 过多的逐顶点计算
  • 片元处理
    • 过多的片元(可能是分辨率造成的,也可能是overdraw引起)
    • 过多的逐片元计算
  • 带宽
    • 使用了尺寸很大且未压缩的纹理
    • 分辨率过高的帧缓存

三、Unity中渲染分析工具

1.渲染统计窗口 Rendering Statistics Window

  • Game窗口 -> Stats
    在这里插入图片描述
  • 每帧的时间和FPS数目:在Graphics右侧
  • Batches:一帧中需要进行的批处理数目
  • Saved by batching:合并的批处理数目(表明了批处理节省了多少draw call)
  • Tris 和 Verts:需要绘制的三角形顶点数目
  • Screen:屏幕大小以及占内存大小
  • SetPass:渲染使用的Pass数量(可能会造成CPU渲染瓶颈)
  • Visible skinned meshes:渲染的蒙皮网格数
  • Animations:播放的动画数目

2.性能分析器(Profiler)的渲染区域

  • Window -> Analysis-> Profiler,rendering区域
    在这里插入图片描述

3.帧调试器 Frame Debugger

  • Window -> Analysis-> Frame Debugger
    在这里插入图片描述
  • 帧调试器的调试面板上显示了渲染这一帧的所有渲染事件
  • 本例中渲染数目为13个,其中包含9个Draw Call

4.其他性能分析工具

  • 高通的Adreno分析工具:可以对不同的测试机进行详细的性能分析
  • 英伟达NVPerHUD:可以得到几乎所有需要的性能分析数据
  • PowerVRAM的 PVRUniSCo shder分析器
  • 等等

四、减少Draw Call的数目

  • 批处理:减少每一帧需要的draw call数目,
  • 相同材质的物体可以一起处理,它们之间的不同仅仅再与顶点数据的差别
  • 两种批处理方式
    • 动态批处理:
      • 由Unity自动完成,物体可以移动
      • 限制很多
    • 静态批处理:
      • 自由度高,限制少
      • 可能会占用更多的内存,物体不可以移动

1.动态批处理

  • 原理:每一帧把可以进行批处理的模型网格进行合并,再把合并后的模型数据传给GPU,然后使用同一个材质进行渲染
  • 限制:(随着Unity版本更新会有不同)
    • 进行动态批处理的网格的顶点属性规模有限制
    • 需要保证物体指向光照纹理中同一个位置
    • 多Pass的Shader会中断动态批处理——有时需要额外的Pass来添加更多的光照效果

2.静态批处理

  • 原理:只在运行开始阶段,把需要批处理的模型合并到一个新的网格结构中(不能在运行时刻移动),但只需要进行一次合并,所以比动态处理更高效
  • 性能瓶颈:当在批处理前一些物体就共享了网格,在内存中每个物体都会对应一个该网格的复制品,即一个网格会变成多个网格发给GPU
  • 如果场景中包含了平行光以外的光源,并在Shader中定义了额外的Pass来处理,这些Pass不会被批处理的
  • 使用:勾选物体的Static

3.共享材质

  • 使用同一个材质(不是同一个Shader)才可以使用批处理
  • 如果想要微调一些参数:使用网格的顶点数据(最常见的是顶点颜色数据)来存储这些参数
  • 如果要脚本访问共享数据,应该是 Renderer.sharedMaterial 而不是 Renderer.material

4.批处理注意事项

  • 尽可能选择静态批处理,但小心内存消耗
  • 小心动态批处理的限制
  • 游戏中的小道具可以使用动态批处理
  • 包含动画的物体,如果有不动的部分可以标为static
  • Shader中如果存在基于模型空间下的坐标运算时,不能使用批处理 DisableBatching标签来让Shader不会被批处理
  • 半透明渲染的物体时,由于严格的渲染顺序,批处理可能不成功

五、减少需要处理的顶点数目

1.优化几何体

  • 减少三角形面片数量:去除对模型没有影响或肉眼难以察觉的顶点,降低模型复杂度
  • 避免硬边和纹理分离: 移除不必要的硬边和纹理衔接,减少顶点拆分,降低顶点数量

2.模型的LOD技术 Level of Detail

  • 原理:当一个物体原理摄像机时,LOD减少模型上的面片数量,从而提高性能
  • Unity实现:使用 LOD Group 组件为对象设置不同 LOD 等级的模型,Unity 会自动选择合适的模型进行渲染

3.遮挡剔除技术 Occlusion culling

  • 用来消除那些在其他物件后面看不到的物件
  • 同时减少CPU和GPU的符合,CPU可以提交更少的Draw Call,GPU处理的顶点和片元也更少了
  • 实现可以看unity手册相关内容

六、减少需要处理的片元数目

  • 这部分优化重点在减少overdraw

1.控制绘制顺序

由于深度测试,物体都是从前往后绘制的,很大程度上减少了overdraw

  • 在Unity中,渲染队列数目小于2500(“Background”“Geometry”和“AlphaTest”)的对象都是不透明的,从后往前绘制;但“Transparent”“Overlay”等物体是从后往前绘制的
  • 利用渲染队列: 将物体分配到合适的渲染队列,确保不透明物体从前向后渲染,避免半透明物体造成 overdraw
  • 调整渲染队列顺序: 根据物体在场景中的位置和重要性,调整渲染队列的顺序,例如先渲染主要角色,再渲染敌方角色和场景物体

2.警惕透明物体

对于半透明物体来说,由于没有开启深度写入,从后往前渲染——几乎一定会造成overdraw

  • 减少大面积半透明物体: 减少场景中大面积半透明物体的数量,例如 GUI 元素,避免造成过多的 overdraw
  • 优化半透明物体渲染: 在移动平台上,尽量减少透明度测试的使用,改为使用透明度混合,并注意透明物体的绘制顺序

3.减少实时光照和阴影

对于逐像素的光源来说,被这些光源照亮的物体需要再被渲染一次,还不能使用批处理操作(额外的Pass无法批处理)

  • 使用烘焙光照: 将静态物体的光照信息烘焙到光照纹理中,避免实时计算,降低 CPU 和 GPU 负担
  • LUT 查找纹理:将光源方向、视角方向、法线方向等参数存储在LUT中。在运行时对LUT采样即可得到光照模型(更复杂的BRDF模型)。主角用更大分辨率的LUT,NPC用小的LUT可以优化性能
  • 限制实时光源数量: 减少场景中点光源的数量,避免过多的逐像素光照计算,并使用逐顶点光照代替逐像素光照
  • 优化实时阴影: 尽量减少实时阴影的使用,对静态物体使用烘焙阴影,对动态物体使用合适的实时阴影技术

七、节省带宽

1.减少纹理大小

纹理长宽比最好是正方形,且长宽值为2的整数幂

  • 纹理图集:将多个纹理合并成一张大图,减少Draw Call 和纹理切换次数
  • 多级渐远纹理技术mipmapping:纹理勾选Advanced后,可以勾选 Generate Mip Maps 来生成纹理金字塔,动态选择
  • 纹理压缩:将纹理压缩成更小的格式,例如 PVRITC、DXT、ATC 等,节省存储空间和带宽

2.利用分辨率缩放

  • 根据设备性能调整屏幕分辨率,例如在低性能设备上降低分辨率,在高性能设备上提高分辨率
  • 使用 Screen.SetResolution 函数设置屏幕分辨率

八、减少技术复杂度

1.Shader 的 LOD 技术

只有 Shader 的 LOD 值小于某个设定值,该 Shader 才会被使用,超过设定值的 Shader 将不会被渲染,可以在 SubShader 中设置 LOD 值,或使用 Shader.maximumLOD 或 Shader.globalMaximumLOD 设置允许的最大 LOD 值

2.代码优化

  • 尽可能使用低精度浮点值进行运算:例如 half、fixed 等,减少计算时间和内存占用。
  • 尽量减少从顶点着色器传递给后续阶段的插值变量数量,例如将多个纹理坐标打包到一个 float4 变量中。
  • 避免使用复杂的数学函数:例如 sin、tan、pow、log 等,可以使用查找表替代。
  • 分支循环: 尽量避免使用分支语句和循环语句,这些语句会影响 GPU 并行效率。
  • discard 操作: 避免使用 discard 操作,因为它会影响 GPU 的一些优化策略。
  • 全屏后处理: 尽量避免使用全屏的屏幕后处理效果,例如 Bloom、热扰动等,可以使用低精度运算或查找表优化。
  • 合并特效: 将多个屏幕后处理特效合并到一个 Shader 中,减少绘制次数和计算量。
  • 硬件缩放: 根据设备性能调整游戏渲染效果,例如在低性能设备上关闭部分特效,在高性能设备上开启更多特效。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 企业培训 | CATIA数字样机培训
  • 为什么Spring不推荐@Autowired用于字段注入
  • Facebook Dating:社交平台的约会新体验
  • 专业140+总分420+天津大学815信号与系统考研经验天大电子信息与通信工程,真题,大纲,参考书。
  • docker部署Guacamole手册
  • SpringBoot应用从jar包部署改为war包部署要做哪些修改
  • SpringCloud---服务注册(Eureka)
  • Ubuntu 24.04 LTS 桌面安装MT4或MT5 (MetaTrader)教程
  • JAVA的接口和实现类
  • Power Shell查看进程、排序、打印出前五
  • 【软考】UML中的关联关系
  • 低功率范围内的MOSFET表征
  • Mysql数据库的索引、事务和存储引擎
  • 面试题:Java中堆内存和栈内存的区别,缓存数据是把数据放到哪里
  • unittest框架和pytest框架区别及示例
  • .pyc 想到的一些问题
  • bearychat的java client
  • es6(二):字符串的扩展
  • Java小白进阶笔记(3)-初级面向对象
  • leetcode讲解--894. All Possible Full Binary Trees
  • MD5加密原理解析及OC版原理实现
  • Nodejs和JavaWeb协助开发
  • Octave 入门
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Python语法速览与机器学习开发环境搭建
  • Vim 折腾记
  • 阿里云Kubernetes容器服务上体验Knative
  • 测试如何在敏捷团队中工作?
  • 分享一份非常强势的Android面试题
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 警报:线上事故之CountDownLatch的威力
  • -- 数据结构 顺序表 --Java
  • 协程
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​补​充​经​纬​恒​润​一​面​
  • #Datawhale AI夏令营第4期#AIGC文生图方向复盘
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • (27)4.8 习题课
  • (4.10~4.16)
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (转)Linux下编译安装log4cxx
  • (自用)gtest单元测试
  • .NET C# 配置 Options
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET MVC第三章、三种传值方式
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET大文件上传知识整理
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)