找回密码
 立即注册
查看: 285|回复: 0

Unity的渲染优化系列(一)

[复制链接]
发表于 2023-3-2 12:59 | 显示全部楼层 |阅读模式
鸽了比较久没更新,最近打算重拾这个习惯,继续边写边总结;打算开一个渲染优化系列,后续不定时更新;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...

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 14:44 , Processed in 0.087366 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表