Dynamic Batching不生效该怎么办

技术Dynamic Batching不生效该怎么办Dynamic Batching不生效该怎么办,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。最近在项目开发

动态批处理不生效怎么办?我相信很多没有经验的人对此无能为力。为此,本文总结了问题产生的原因及解决方法。希望你能通过这篇文章解决这个问题。

最近在项目开发过程中,偶然发现游戏场景的绘制占用了很多batch,几乎一个模型显示占用了一个Batch,批处理保存的数量几乎为零,也就是没有进行批处理渲染优化。显然,这与预期相差甚远,因为场景中虽然有上百个模型可以绘制,但大部分都是完全相同的卡片模型,引用相同的材质球,大部分都可以由Unity自动动态批量进行合并和批量处理。到底出了什么问题?

所以看一下Unity手册,看看动态配料的规则,可以总结如下:

通常,Unity只支持网格小于900个顶点的对象的动态批处理。如果在着色器中使用顶点位置、法线和紫外线值,则仅支持300个或更少顶点的对象。如果使用顶点位置、法线、UV0、UV1和切线向量,则仅支持180个顶点以下的对象。

如果两个对象的比例只是镜像,比如分别为(-1,-1,-1)或(1,1,1),则不会动态批处理。

具有不同参考材质实例的对象不会被动态批处理,即使两个对象的材质没有本质上的不同。一个简单的例子意味着同一素材被实例化为两个副本,分别被A和B引用,所以A和B不会被动态批处理,因为它们引用了两个不同的例子。

具有光照贴图的对象不会被动态批处理,除非它们指向光照贴图的相同部分。

具有多个通道的着色器对象不会被动态批处理。

经过简单考察,该模型在1、2、4、5点满足Unity的要求。所以我开始怀疑不同的材质实例引用导致了问题。

Dynamic  Batching不生效该怎么办

查看检查器,我们可以看到网格渲染器引用的材质确实是需要的着色器,但是后面添加了单词Instance。单击图中的红色框,“项目”窗口不会跳转到着色器文件的所有位置,这表明该材质是在运行时实例化的,而不是Prafab在预设期间指向的着色器引用。由此,我们可以推断每个模型实例化自己的材质实例,这导致没有动态批处理。如果你知道问题的原因,你需要知道问题是什么。检查绑定在对象上的脚本,并检查与材料相关的代码。你可以看到有两个地方:

privateTexture _ mainPlaneTexprivateTexture _ flashPlaneTexpublicmesrendererm _ rendererPlane;private material _ cached plane material=null;privatatematerialcachedplanemat

{获取

{ if(_ cached plane material==nullm _ render plane!=null)

{

_ cachedPlaneMaterial=m _ rendererplane . material;

}            return _cachedPlaneMaterial;
        }
    }

    private void SetGray(bool bGray)
    {        if (bGray)
        {
            cachedPlaneMat.SetTexture("_MainTex", _flashPlaneTex);
        }        else
        {
            cachedPlaneMat.SetTexture("_MainTex", _mainPlaneTex);
        }
    }

这个模型有模型变灰色的需求,实现方式是通过获取该物体的material,再视情况将MainTexture设置为正常/变灰贴图。出问题的地方十有八九就在这块代码。查看MeshRenderer的接口,原来Unity提供了两个获取Material的方法接口,分别是material及sharedMaterial。
搞懂这两个接口的区别,弄清楚Unity在底层到底搞了什么鬼,估计离真相就不远了。

Renderer.material

Returns the first instantiated Material assigned to the renderer.
Modifying material will change the material for this object only.
If the material is used by any other renderers, this will clone the shared material and start using it from now on.

Unity官方说当使用Renderer.material获取Material引用时,会把Render里Materials列表第一个预设的Material进行实例化,并将返回实例。这样,当我们对这个物体的Material进行修改时,只会修改实例,而不会修改到最原本的材质球,比如我们将同个模型Prafab拖放N多个到场景里,当我们对其中一个模型A的材质球进行修改,比如替换贴图,其他模型是不会受到影响的,因为A修改的仅仅只是自己实例化出来的材质球。

Renderer.sharedMaterial

The shared material of this object.
Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.
It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.

而如果调用Renderer.sharedMaterial接口,Unity则不会多此一举地帮我们做实例化,再返回实例了,直接就是返回最原本的材质球。还是上面那个例子,当我们给A模型的材质球替换贴图,会发现场景的所有模型都被替换了贴图。

看完了两个接口的差异,也终于明白了问题的根本原因。为了实现模型变灰的需求,代码里使用Renderer.material来获取material实例,殊不知每个物体都各自持有了一份不同的material实例,使得Unity没办法将这些一模一样的物体进行合批渲染,当同屏显示的物体数目多达上百,就意味着多出上百个不必要的Drawcall,多了不必要的损耗。

而这个问题也不能简单地将Renderer.material改为调用Renderer.sharedMaterial就解决了,总不能把一个模型变灰,所有模型都要跟着变灰吧?正确的解决方法就是预设正常/灰色两个材质球,根据不同的情况替换材质。

最后贴下优化前后,场景Drawcall的对比:

Dynamic Batching不生效该怎么办

优化前

Dynamic Batching不生效该怎么办

优化后

可以看到,在同屏模型较多的情况下,Batch数由近100骤降到2,基本都被Unity动态合批处理了。

看完上述内容,你们掌握Dynamic Batching不生效该怎么办的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/94851.html

(0)

相关推荐

  • Java(10)File递归字节流

    技术Java(10)File递归字节流 Java(10)_File递归字节流1.File类
    1.1File类概述和构造方法【应用】File类介绍它是文件和目录路径名的抽象表示
    文件和目录是可以通过Fil

    礼包 2021年12月14日
  • C++11的array容器怎么使用

    技术C++11的array容器怎么使用本篇内容介绍了“C++11的array容器怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,

    攻略 2021年11月24日
  • 怎么解决MySQL server PID file could not be found问题

    技术怎么解决MySQL server PID file could not be found问题本篇内容介绍了“怎么解决MySQL server PID file could not be found问题”的有关知识,在

    攻略 2021年11月18日
  • 二手车好吗,你觉得二手车能不能买,为什么

    技术二手车好吗,你觉得二手车能不能买,为什么二手车可以买二手车好吗,但是你要买对品牌,不是什么车都可以买二手的。接触了汽修行业十几年,我来跟你说说哪些二手车可以买,哪些二手车不能买吧。
    美系车,通用系的,二手是真的不敢买

    生活 2021年10月28日
  • ADO.NET SqlConnection怎么使用

    技术ADO.NET SqlConnection怎么使用这篇文章主要讲解了“ADO.NET SqlConnection怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“

    攻略 2021年12月3日
  • 感觉拼音,如果让你用拼音来写QQ空间的日志

    技术感觉拼音,如果让你用拼音来写QQ空间的日志估计真要用汉语拼音写日志感觉拼音,汉语拼音创始人,17世纪的法国(也算比利时)传教士金尼格也能看懂吧。
    中国自己的拼音第一人卢戆章却未必能看懂(他一直擅长拼音闽南语)
    方言是

    生活 2021年10月20日