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)

相关推荐

  • 美国服务器提供的功能和优势

    技术美国服务器提供的功能和优势美国服务器相比其他地区的海外服务器拥有多种优势,包括安全性,速度和可靠性。美国服务器支持用户完全控制权限,并保护您的数据免受未经授权的访问。美国服务器还允许您轻松升级美配置及其服务。如有必要

    礼包 2021年12月16日
  • [zoj3990]Tree Equation

    技术[zoj3990]Tree Equation [zoj3990]Tree Equation记$dep(T)$为树$T$的深度(根节点深度为0),则有$\begin{cases}dep(A+B)=\m

    礼包 2021年10月27日
  • 数据库原理知识点有哪些

    技术数据库原理知识点有哪些这篇文章主要介绍“数据库原理知识点有哪些”,在日常操作中,相信很多人在数据库原理知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”数据库原理知识点有哪些”

    攻略 2021年11月3日
  • Oracle11g报警功能识别是否会忽略或吞掉错误的程序

    技术Oracle11g报警功能识别是否会忽略或吞掉错误的程序Oracle11g报警功能识别是否会忽略或吞掉错误的程序,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易

    攻略 2021年11月29日
  • 饺子怎么煮,如何煮饺子,加多少水好呢

    技术饺子怎么煮,如何煮饺子,加多少水好呢1饺子怎么煮、将锅中加入3000ml 水,然后点火开始烧水,烧水过程中可以往锅中添加2勺食盐,目的防止饺子粘锅。2、水开锅之后,将包好的水饺倒入其中,轻微的搅拌,防止饺子皮黏住锅底

    生活 2021年10月20日
  • oracle提供哪几种分区表的特点(oracle分区表分区备份有哪些方法)

    技术ORACLE分区表日常维护方法是什么这篇文章主要讲解了“ORACLE分区表日常维护方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ORACLE分区表日常维护方

    攻略 2021年12月22日