【Unity】学习笔记 | 性能优化(一)—— 渲染

Unity中,每一帧的渲染CPU和GPU都做了些什么

1. CPU检查场景中每个对象,判读他们是否应该被渲染。CPU收集即将被渲染的对象信息,并把这些信息分类为渲染指令(即draw calls)

2. Draw call包含网格数据以及网格该如何被渲染在某些场景,共享设置的一些对象可能会被合并为一个draw call,合并不同对象的数据到同一个draw call被称作batching

3. CPU给每个draw call创建一个数据包,称为batch,每一个batch必须包含一个draw call

4. CPU会发出指令,使GPU改变一些渲染状态。这个指令被称为SetPass call,SetPass call通知GPU,如何去渲染下一个网格。只有在渲染下一个网格时,渲染状态相对于渲染上一个网格发生了变化,才会调用SetPass call

5. CPU把draw call发送给GPU,通知GPU使用最近的SetPass call去渲染指定的网格

6. 有时,batch可能需要不止一个的pass。pass是shader代码的一部分,而新的pass需要改变渲染状态。对于batch中的每个pass,CPU必须发送一个新的SetPass call,并必须再次发送draw call

7. GPU按照CPU发送的指令顺序处理这些指令

8. 如果当前任务是SetPass call,那么GPU更新渲染状态

9. 如果当前任务是draw call,那么GPU渲染网格。渲染网格发生在很多阶段,不同阶段的shader代码可以定义渲染。其中:顶点着色器vertex shader告诉GPU怎么处理网格的顶点。片元着色器fragment shader告诉GPU怎么绘制单独的像素

10. 以上过程会重复执行,直到所有CPU发送的任务都被GPU完成

渲染问题有两个基本的原因:第一类问题是由低效的渲染管线引起。当渲染管线中一步或者多步花费了太长时间,打断了平滑的数据流时,渲染管线会很低效。渲染管线的低效被称为瓶颈。第二类问题是由于,渲染管线被塞入了太多的数据。即使是最高效的渲染管线,对于一帧中可以处理的数据量也是有限制的

渲染优化的主要目的就是减少渲染的工作量,控制渲染的工作量是保证效率的根本,而每帧渲染的顶点数量是衡量渲染工作量最直观的标准之一

  • 每帧可渲染的顶点数量主要取决于设备的CPU和GPU。 不过通常来说PC游戏每帧渲染的顶点个数不宜超过2M,移动游戏每帧渲染的顶点数量不宜超过0.1M


CPU渲染优化

在渲染每一帧中CPU会完成三个任务:确定绘制的物体 —> 为GPU准备命令 —> 发送命令给GPU。这些任务通过多线程完成。多线程允许不同的任务同时执行,当渲染任务被分发到不同的线程时,称为多线程渲染

Unity渲染过程中和三类线程相关:

主线程,渲染线程和工作线程。主线程用于我们游戏的主要CPU任务,包括一些渲染任务。渲染进程是专门用于发送命令给GPU的。每个工作线程执行一个单独的任务,例如剔除和网格蒙皮。哪些任务执行在哪个线程,取决于游戏运行的硬件和游戏的设置。例如,CPU的核心数量越多,就会生成越多的工作线程数。因此,在目标硬件上进行性能分析是十分重要的,在不同的设备上,项目的表现可能相差很多

由于多线程渲染非常复杂并且依赖硬件,在我们尝试改进性能时,必须首先找到是哪些任务导致了CPU问题(可以通过Profiler来检查)。如果我们的游戏运行缓慢是因为在一个线程上剔除操作花费了太长的时间,那如果我们在另一个线程上降低发送给GPU命令的时间是不会有什么帮助的

发送命令到GPU花费时间过长是引起CPU限制的最常见的原因,其最耗时的操作是SetPass call。如果CPU限制是由发送命令到GPU引起的,那么降低SetPass的数量通常是最好的改善性能的方式(Unity运行后在Statistics窗口中可以观察到其数量):

1. 减少要渲染的对象数量

        通常可以同时降低SetPass call和batches的数量

        1.1 手动减少场景中物体的数量

        比如在多人游戏中,不影响游戏性和玩家体验的前提下,减少可见玩家的数量

        1.2 Occlusion Culling(遮挡剔除)

        当一个物体被其他物体遮挡住,不在摄像机的可视范围内时不对其进行渲染
        流程:选中所有物体,在static下拉菜单中勾选Occlusion Static 和 Occludee Static →→ Window > Occlusion Culling →→ Occlusion Culling面板中Bake

在Occlusion bake中有三个参数:

Smallest Occluder:设置最小遮挡物的尺寸,当遮挡物的长度或者宽大于设定值时,该物体才能够遮挡住后面的物体

Smallest Hole:设置最小孔的尺寸,当穿过物体内部的孔或者多个物体堆叠形成的孔的大小小于设定的值时,遮挡剔除烘焙将忽略该孔的存在

Backface Threshold:设置背面移除阈值,用于优化场景,当该值为100时,摄像机拍摄不到的背面信息也会完整保留;当该值较小时,系统将对背面信息进行优化甚至去掉背景信息

Occlusion Culling是对于场景优化最重要的技术之一,对于较大的场景一定要使用遮挡剔除,大场景中过多的绘制渲染会造成很大的性能损耗

        1.3 摄像机Clipping Planes

        通过摄像机的Clipping Planes 的Far裁剪远端,降低摄像机的绘制范围

2. 减少每个要渲染的对象的渲染次数

        通常可以降低SetPass call,减少实时光照、阴影、反射计算

        2.1 Lightmap(光照贴图)

        Unity灯光默认是实时光照,烘焙灯光效果生成光照贴图,大大减少Setpass Calls

        流程:被光照到的物体static下拉菜单中勾选上Lightmap Static →→ 把所有光源的Mode设置为Baked →→ Window > Lighting > Settings 点击Generate Lighting生成光照贴图

        2.2 阴影

        流程:Edit > Project Settings > Quality 设置阴影属性

阴影 (Shadows):此项决定应该使用哪种阴影类型,硬阴影和软阴影 (Hard and Soft Shadows),仅硬阴影 (Hard Shadows Only),禁用阴影 (Disable Shadows)

阴影分辨率 (Shadow resolution):阴影可以按低 (Low) 、中 (Medium) 、高 (High) 和很高 (Very High)分辨率进行渲染,分辨率越高,处理开销就越大

阴影投射 (Shadow Projection):从平行光源投射阴影有两种方法,紧密配合 (Close Fit) 渲染分辨率更高的阴影,但是如果摄影机移动,这些阴影有时就会有些许摇晃。稳定配合 (Stable Fit) 渲染分辨率更低的阴影,而阴影不会随摄影机的移动而摇晃

阴影距离 (Shadow Distance):从摄影机处可以看见阴影的最大距离。超出此距离的阴影将不会被渲染

阴影层叠 (Shadow Cascades):阴影层叠 (shadow cascades) 数可设置为零、二或四。层叠数越高质量越好,但这要以处理开销为代价

        2.3 反射探头

3. 合并要渲染的对象的数据

        可以降低batches数量

       3.1 动态批处理和静态批处理

        在Unity中如果动态物体共用相同的材质,那么Unity会自动对这些物体进行批处理。动态批处理操作是自动完成的;静态批处理网格会合并,需要使用同一个网格同一个材质(使用静态批处理时,只需要同一个材质且批处理的物体处于静态,同时勾上Static)

        静态批处理没动态批处理的诸多限制,且不会造成CPU损耗,但会有更高的内存占用
     

        3.2 纹理图集

        纹理图集是把大量的小纹理合并为一张大的纹理图的技术

        Unity内置了图集工具老版本为Sprite Packer,新版本为SpriteAtlas


GPU渲染优化

优化GPU渲染问题主要从三个方面来进行:顶点,填充,带宽,目的是改善显存带宽问题

顶点处理 GPU需要渲染网格中每一个顶点。顶点处理的消耗受两方面影响:必须渲染的顶点数量,以及在每个顶点上要进行的操作数量

填充率 GPU在屏幕上每秒可以渲染的像素数。如果游戏受到填充率的限制,说明每帧尝试绘制的像素数量超过了GPU的处理能力

显存带宽 GPU读写其专用内存的速度。如果游戏速度受限于显存带宽,通常可能是由于使用的纹理太大,GPU无法快速处理

1. 纹理压缩

        纹理压缩技术可以同时极大的降低纹理在磁盘和内存中的大小,

2. Mipmap

        如果场景包含距离摄像机很远的物体,可以使用mipmap,模型的贴图会根据摄像机距离模型的远近而调整不同质量的贴图显示,内存会变大
        流程:在贴图上Advanced选中Generate Mip maps,点击Apply确定

3. LOD

        LOD与Mipmap类似,根据距离的远近使用不同精度模型,远处选择低精度的模型,近的时候选择高精度模型,减少模型上面的顶点和面片数量从而提高性能
        Mipmap可以自动生成八张精度不同的贴图,而LOD必须准备好三个不同精度的模型

        流程:低中高模型挂在同一个组下,添加组件LOD Group →→ 在LOD Group中,添加对应百分比可见度的模型

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值