unityloverz 发表于 2023-3-2 12:59

Unity的渲染优化系列(一)

鸽了比较久没更新,最近打算重拾这个习惯,继续边写边总结;打算开一个渲染优化系列,后续不定时更新;AssetBundle系列也会同步更新~先立个flag
最近看了一篇Unity Learn官方的性能优化博客,总体而言讲得比较详细,在此纪录并且分享一下。(翻译一下hhh)
参考链接:
Fixing Performance Problems - 2019.3 - Unity Learn概述

这篇文章大概分为三部分:

[*]Unity是如何渲染每一帧的
[*]渲染的时候可能会发生哪些问题
[*]如何修复/优化这些渲染问题
一个亘古不变的定律,任何优化都是权衡利弊的过程,是个复杂的过程,每个case可能都会由不同的原因造成。在某方面得到优化的同时势必带来一些副作用,优化的过程就是如何取舍的问题。
这篇文章会介绍一些常见的导致渲染性能的问题,也会介绍一些常见的解决方案。
渲染简介

首先介绍一下Unity的渲染流程,看看Unity是怎么渲染每一帧的。
简而言之,渲染可以简单粗暴地分为3个部分:

[*]CPU决定哪些物体需要被绘制,要用什么方式绘制
[*]CPU发送一些指令给GPU
[*]GPU执行CPU的指令绘制物体
保证渲染流畅的唯一法则就是让渲染流水线可以流畅运行,即不要有某一个环节占用了太多时间导致整个流水线循环被破坏。
介绍一些CPU和GPU在整个渲染流程中的一些具体细节。
每一帧渲染中,CPU做了以下工作:

[*]CPU会遍历物体以确定哪一些需要被渲染。比如,在相机视场角外的物体不会被渲染。不被渲染的物体就称为被剔除(Culled),常见的剔除有视场角剔除,遮挡剔除等。
[*]CPU收集将要渲染的对象的信息,并将这些数据整理成为不同的Drawcall. 一次Drawcall包含了单个mesh数据以及如何渲染这个mesh(例如,使用哪张贴图). 当然,一次Drawcall并不一定只渲染单个mesh数据,如果有合批Batching则会有多个物体在一次Drawcall中一起绘制。
[*]CPU为Drawcall创建一个数据包就叫批次(Batch). 一个Batch可能包含多个Pass和DrawCall.(Pass指shader中包含的pass通道,切换Pass意味着需要调用SetPassCall)
[*]CPU可以向GPU发送命令更改一些变量属性,这些变量统称为渲染状态。这个命令就是SetPassCall. 一个SetPassCall告诉GPU为下一个物体绘制需要准备哪些状态,所以只有在下一个物体绘制需要切换状态时才会有一次SetPassCall.
[*]CPU发送DrawCall指令给GPU,告诉GPU用最新的渲染状态去渲染某个mesh(可能不止一个物体的mesh,可能是合批后的mesh).
此处涉及的Drawcall, Batch, SetPassCall等概念较复杂,可以在网上搜索更详细的解答。
GPU做的工作:

[*]GPU会按顺序处理来自CPU的命令
[*]如果是SetPassCall命令,则GPU会更新渲染状态
[*]如果是DrawCall命令,则GPU会开始渲染mesh
[*]GPU一直运行直到处理完所有CPU发过来的命令
渲染问题的类型

要保证渲染每一帧正常进行就需要CPU和GPU在每一帧的时间内都能做完所有的事情,如果某一个环节超时,就会导致整个渲染流程被delay,即渲染一帧超时,就会导致帧率下降。
渲染问题有两个最基本的原因:

[*]不高效的渲染管线。即渲染流水线因为某个环节耗费大量时间无法高效运转,则会导致渲染问题
[*]渲染的数据过量。即时渲染流程是高效的,但如果要渲染的数据太多,就会导致渲染出现瓶颈
所有的渲染问题都可以归结于CPU瓶颈或GPU瓶颈,处理渲染问题的很重要前置处理就是找出问题是出在CPU还是GPU上。

如何找到渲染瓶颈的具体原因

首先要明确渲染瓶颈是由于CPU还是GPU导致的;其次要找到是哪个环节导致的瓶颈。这需要大量的工具辅助。常用的问题分析工具:

[*]Unity自带的Profiler (https://docs.unity3d.com/Manual/ProfilerWindow.html)



Unity Profiler


[*]Unity自带的FrameDebugger (https://docs.unity3d.com/Manual/FrameDebugger.html)



Unity FrameDebugger


[*]苹果自带的GPU Frame Capture神器,确认了是GPU的问题之后可以使用这个神器,有非常详细的数据(https://developer.apple.com/documentation/metal/debugging_tools/enabling_frame_capture),可以列出每个DrawCall的耗时,渲染管线每个流程的耗时。强推!!
此处可以查看B站UP主的一个优化系列教程,很好的一个系列教程: https://www.bilibili.com/video/BV14S4y1w7vw/?spm_id_from=333.999.0.0&vd_source=8ccbd5d7b8a9e948b5b05ccb3fc4b9c5



XCode GPU Capture


[*]RenderDoc 本人比较少用-_-,不过也是一个神器,可以集成到Unity Editor中,也是很推荐的
https://docs.unity3d.com/2020.1/Documentation/Manual/RenderDocIntegration.html
https://renderdoc.org/



RenderDoc

To be continue...
页: [1]
查看完整版本: Unity的渲染优化系列(一)