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)

相关推荐

  • 如何mysql 数据库1024问题

    技术如何mysql 数据库1024问题如何mysql 数据库1024问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。max_allowed

    攻略 2021年10月25日
  • 如何用Python实现图像文字识别OCR工具

    技术如何用Python实现图像文字识别OCR工具这篇文章主要介绍“如何用Python实现图像文字识别OCR工具”,在日常操作中,相信很多人在如何用Python实现图像文字识别OCR工具问题上存在疑惑,小编查阅了各式资料,

    攻略 2021年12月11日
  • oracle中出现ora-01013错误怎么办

    技术oracle中出现ora-01013错误怎么办小编给大家分享一下oracle中出现ora-01013错误怎么办,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们

    攻略 2021年11月12日
  • lua 动态sql解析(lua语言系统防入侵源码)

    技术监控Agent集成Lua引擎怎么实现多维度日志采集监控Agent集成Lua引擎怎么实现多维度日志采集,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。在

    攻略 2021年12月18日
  • HttpServletResponse与HttpServletRequest

    技术HttpServletResponse与HttpServletRequest HttpServletResponse与HttpServletRequest一、HttpServletResponse

    礼包 2021年11月11日
  • 荸荠怎么煮,赤豆煮荸荠的制作方法是怎样的

    技术荸荠怎么煮,赤豆煮荸荠的制作方法是怎样的制作赤豆煮荸荠的原料有:赤豆100克,荸荠100克,料酒10毫升,姜5克,葱10 克,盐3克,鸡精3克,鸡油30毫升荸荠怎么煮。制作方法:(1 )将赤豆去泥沙,洗净;荸荠去皮,

    生活 2021年10月26日