您可以做几件事来提高绘图性能。
你说他们很远。您可以使用LOD减少这些树的顶点数,从而减少遍历所有绘制顶点所需的时间。即使这很可能不是手头的问题(GTX1080仅包含1万棵树,每棵树有200个tris,gpu的数字很小),我仍然将其包括在内。Billboarding是实现最低LOD级别的有效工具,因为它本质上是始终面向摄像机并带有树的渲染图像的平面。它失去了深度感,这就是为什么它适合最低级别的原因,因为玩家很可能不会注意到差异。
您启用了批处理功能吗?如果网格的顶点数很少,通常会自动完成动态批处理。也可以通过选中父游戏对象上统一编辑器中的复选框使树变为静态来尝试进行静态批处理。这不适用于动画对象。您需要这些对象共享材料才能完成这项工作。
自定义批处理允许您通过自己生成块来控制渲染,而不是由统一处理它,并且还可以为较大的网格进行批处理。这可以通过Mesh.CombineMeshes轻松完成。这也不适用于动画对象。您需要这些对象共享材料才能完成这项工作。您可能希望将您的世界划分为某种块,并根据这些块创建批次。这些块的生成方式实际上取决于相机在世界上的移动方式。
在着色器上启用实例化。实例化使引擎可以通过一个绘制调用来绘制多个对象(具有相同的网格)。您需要使对象具有共享的网格和共享的着色器才能起作用。材质可以变化,但是着色器必须支持所有不同的变化属性。
为了使引擎更好地创建实例渲染批处理,您可能希望将相同的网格划分到场景中。如果一个网格物体始终具有相同的材质,则还可以使用材质渲染队列来获得良好的效果。在开发当前正在开发的移动游戏期间,我使用它来将测试场景中的抽奖次数减少了一半以上。另外,自Unity 5.6起,请确保Enable Instancing
选中材料中的复选框。
一般情况下,请减少通话和SetPass通话。这些是您的GPU绘制内容的原始调用,而且开销很大。减少抽奖活动(批处理和实例化正在做的事情)将提高您的CPU可以提供的整体性能,因为它需要减少等待时间。SetPass调用是对当前着色器的更改,因此,如果您使用许多不同的材质,则将有多个SetPass调用,这也会导致CPU等待一点时间。
如果场景很大,并且您的CPU时间花费在浏览场景中的所有对象上,请尝试减少场景中的对象。对一些树进行分组,而不是单独放置它们并将它们作为单个对象。还要确保您没有移动树或父对象,因为这会使Unity放弃缓存的变换并重新计算整个场景树。
如果场景很大,而您的CPU时间仍然主要花在Unity上,而遍历场景树以列出所有对象,那么您可以做的一件事就是不要让Unity处理渲染。如果您有更好的跟踪可绘制对象的方法,则可以使用CommandBuffer.DrawMeshInstanced或Graphics.DrawMeshInstanced手动绘制它们。我不会对此进行详细介绍,因为它要高级得多,并且涉及淘汰自己和其他人。
如果静态或动态批处理无法正常工作(可以通过检查框架调试器看到),则需要确保确实使用了共享材料,并且不要通过调用意外复制材料meshRenderer.material
。呼叫.material
将复制您的物料并中断批次。使用.sharedMaterial
代替。
从Unity 5.6开始,您可以使用Frame Debugger来确定为什么某些drawcall不与先前的drawcall批处理的原因。在尝试减少游戏的吸引声时,这将非常有用。
与静态/动态/自定义批处理相比,实例化具有以下优点:
- 使用较少的内存,因为网格不必在内存中重复
- 可以使用多种材质,仅需要共享着色器
- 物体可以动画
作为缺点,它是Unity中的新功能,可能有点不稳定。同样,较旧的或移动设备的GPU不一定支持实例化。