Unity性能优化(二)DrawCall与渲染优化

一、DrawCall是什么

DrawCall是渲染管线的一部分,渲染管线就是绘制图像的流程,具体渲染管线和DrawCall是什么我引用一位博主的文章,讲的很清晰,可以去原地址查看

CPU通过调用图形API接口( glDrawElements (OpenGl中的图元渲染函数) 或者 DrawIndexedPrimitive (DirectX中的顶点绘制方法) )命令GPU对指定物体进行一次渲染的操作即为DrawCall。此过程实质上就是在告诉GPU该使用哪个模型的数据(图形API函数的功能就是将CPU计算出的顶点数据渲染出来)。
链接: Unity3D 渲染管线全流程解析

二、如何降低DrawCall

原理:CPU在提交DrawCall的时候,一个mesh和一个texture就对应一次DrawCall,两个mesh一个texture对应两次DrawCall,所以减少DrawCall一般从这两个方面入手,将多个mesh合并成一个,或者用图集将多个texture合并成一个

通过降低mesh

1、静态批处理

Unity静态批处理是一种优化技术,用于在渲染过程中减少绘制调用的数量。在Unity中,每个游戏对象都有一个MeshRenderer组件,用于渲染该对象的网格。当场景中有大量的游戏对象时,每个对象都需要进行一次绘制调用,这会导致性能下降。

静态批处理的目的是将多个游戏对象的网格合并成一个大的网格,然后一次性绘制。这样可以减少绘制调用的数量,提高渲染性能。Unity的静态批处理功能可以自动将静态的游戏对象进行批处理。要启用静态批处理,可以在Unity的Player Settings中勾选"Static Batching"选项。
注意事项:静态批处理的物体需要勾选static状态,并且不能移动

2、动态批处理

如果物体要移动,可以考虑使用动态批处理,但是动态批处理限制条件很大,并且适用于大量物体的渲染,对于少量物体的渲染可能没有明显的性能提升。

3、GPU Instancing

Unity的GPU实例化(GPU Instancing)是一种渲染优化技术,可以在GPU上复制和重用渲染数据,从而减少CPU到GPU的数据传输和渲染调用次数,提高性能。使用GPU实例化可以将多个相同的物体实例化为一个批处理,这些物体可以共享相同的材质和渲染属性。可以一次性渲染多个实例化物体,而不是每个物体都进行单独的渲染调用。使用时在材质上勾选GPU Instancing即可

4、Combine Meshs

手动将多个mesh合并成一个大的mesh,适用于大型静态场景,能起到跟static batch差不多的效果。

示例代码:将代码挂载到父物体上,运行时便会自动合并所有子物体的mesh

[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class ExampleClass : MonoBehaviour
{
    void Start()
    {
        MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combine = new CombineInstance[meshFilters.Length];

        int i = 0;
        while (i < meshFilters.Length)
        {
            combine[i].mesh = meshFilters[i].sharedMesh;
            combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            meshFilters[i].gameObject.SetActive(false);

            i++;
        }
        transform.GetComponent<MeshFilter>().mesh = new Mesh();
        transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);
        transform.gameObject.SetActive(true);
    }
}

通过减少texture

1、使用Atlas(图集)

texture atlas

在Unity中,Atlas(图集)是一种将多个小纹理(Texture)合并成一个大纹理的技术。使用图集可以减少渲染调用次数,提高性能和内存利用率。打包图集以后需要使用uv坐标来确定当前材质需要使用的texture

sprite atlas

跟texture atlas使用方法差不多,不过sprite atlas适用于UI元素

三、其他渲染优化

1、mipmap

贴图的分辨率和最终渲染出来的分辨率是不一样的,根据近大远小原理,远处的物体会缩小,所以对应的贴图也会被缩小,此时会导致模糊,闪烁(摩尔纹效应) 等问题,mipmap是一种根据渲染距离,使用不同大小贴图的技术,不仅能解决上述问题,还能减少性能开销

Mipmap的创建和使用是自动的,只需在纹理导入设置中启用Mipmap选项即可。当Mipmap被启用时,Unity会在导入纹理时自动生成一系列缩小版本的纹理。这些缩小版本的纹理分别是原始纹理的1/2、1/4、1/8…分辨率大小。

注意事项:使用Mipmap会增加纹理的内存占用,因为它包含了多个缩小版本的纹理。

2、LOD (Level of Detail)

多级模型技术,类似于mesh版的mipmap,比如有一个房子,上面有窗台,花盆等细节,当玩家距离较远的时候,再显示这些细节就没有必要了,反正玩家也看不到,这个时候把这些细节删去也几乎不影响效果。

在Unity中,LOD(Level of Detail) Group是一种功能,允许开发者管理和控制场景中物体的细节级别。LOD Group是一个可以添加到游戏对象上的组件,它包含多个LOD级别。

每个LOD级别代表了对象的不同细节级别。例如,第一个LOD级别可能是一个高度详细的模型,而第二个LOD级别可能是一个简化版本,具有更少的多边形。随着相机与物体之间的距离增加,Unity会自动切换到适当的LOD级别,以保持性能。

刺客信条大革命中实现同屏上万NPC就用到了类似的技术,B站有翻译好的视频,非常建议看一下,另外提一嘴,GDC游戏开发者大会,英语全称为 Game Developer Conference,是一年一度的游戏开发者最大的聚会,每年将有数万名游戏开发者参加大会。GDC上有很多大佬讲的游戏方面的知识,质量都很高,其他的视频也可以看一看。
在这里插入图片描述
链接: 【中英双字】《刺客信条:大革命》中的同屏上万NPC是如何实现的「GDC」

3、动静分离

首先要讲一下UGUI中canvas更新的原理,系统会检测当前canvas上是否发生了变动(比如鼠标放到某个按钮上,按钮的颜色发生改变),如果有变动,就会刷新整张Canvas。我们可以考虑使用多个canvas,同一个界面下的UI,可活动的元素放在一个Canvas下,不可活动的元素放在另一个Canvas下,这样就只会刷新活动canvas的页面,减少的性能消耗。

4、SRP Batcher

这块我了解不是很深,这里先借用ChatGpt的回答

Unity SRP Batcher是Unity的一种渲染技术,它是在Unity的脚本化渲染管线(Scriptable Render Pipeline,SRP)中的一部分。SRP Batcher旨在提高渲染性能,通过减少CPU到GPU之间的数据传输和渲染状态切换来优化渲染过程。

SRP Batcher通过将多个渲染调用打包成一个批次来实现性能优化。在传统渲染中,每个渲染调用都会导致一次CPU到GPU的数据传输和渲染状态切换,这会带来较大的开销。而SRP Batcher会将多个渲染调用打包成一个批次,然后一次性传输数据和进行状态切换,从而减少了开销。

使用SRP Batcher可以提高游戏的渲染性能,特别是在处理大量渲染调用时。它可以与Unity的各种渲染特性和效果一起使用,并且可以通过自定义SRP进行扩展和优化。

总之,Unity SRP Batcher是Unity中的一种渲染技术,通过打包渲染调用以减少CPU到GPU之间的数据传输和渲染状态切换来优化渲染性能。

5、2的幂

游戏中使用的图片的宽和高尽量设置为2的幂,这样能保证图片的大小是二的幂字节。因为cpu和gpu一次性能处理的字节数是二的幂,例如cpu一次性能处理8个字节,而图片大小为9个字节,那么就要两个周期来处理,仅仅多了一个字节却要浪费掉一个周期。

6、更多可以考虑入手的地方

减少顶点数量,减少材质数量,减少shader数量(SetPass)等

四、总结

性能优化这块内容比较多,如果每一个都贴上代码讲如何使用,将耗费巨大的精力,本文只是列一个提纲,更深入的内容请大家自行学习,可以结合上文将的Profiler工具一起使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉达哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值