似乎是在Unity5.4中开始支持GPU Instacing,但如果要比较好的使用推荐用unity5.6版本,因为这几个版本一直在改。

这里测试也是使用unity5.6.2进行测试

在5.6的版本里,Instancing不再是一个单独的shader,而是一个开关。

如果使用Instancing功能需要开启,否则调用相关接口时会报错

默认情况下,多个一样的模型会被动态批次合并优化掉,动态批次合并有很多种情况不可用,其中一种就是镜像的情况。

这里用镜像后的实例模型和GPU Instancing做比较

注意,在Unity5.6.2或者之后的版本中,只要材质球勾选Instancing,即自动开启并使用GPU Instancing。

GPU Instancing大致代码如下(用Graphics一次性调用减少了层级对象的创建开销):

  1. void Update()
  2. {
  3. var meshRenderer = template.GetComponent<MeshRenderer>();
  4. var meshFilter = template.GetComponent<MeshFilter>();
  5. var mesh = meshFilter.sharedMesh;
  6. var matrices = new Matrix4x4[instanceCount];
  7.  
  8. for (int i = ; i < matrices.Length; i++)
  9. {
  10. var position = Random.insideUnitSphere * range;
  11. var rotation = Quaternion.LookRotation(Random.insideUnitSphere);
  12. var scale = Vector3.one * Random.Range(-2f, 2f);
  13. var matrix = Matrix4x4.TRS(position, rotation, scale);
  14.  
  15. matrices[i] = matrix;
  16. }
  17.  
  18. Graphics.DrawMeshInstanced(mesh, , meshRenderer.sharedMaterial, matrices);
  19. }

是实时随机的位置,会看见只有13个Batches.

常规实例化测试脚本(挂了正弦运动脚本,注意镜像反转,使其无法动态批次合并):

  1. for (int i = ; i < instanceCount; i++)
  2. {
  3. var instancedTemplate = Instantiate(template);
  4. instancedTemplate.transform.position = Random.insideUnitSphere * range;
  5. instancedTemplate.transform.forward = Random.insideUnitSphere;
  6. instancedTemplate.transform.localScale = Vector3.one * Random.Range(-2f, 2f);
  7. }

大概在1020个Batches

另外我还打了个APK包测了下,居然能在我的红米3S上跑。这就有点厉害了

那么GPU Instacing其实也有一些限制的,比如不支持蒙皮网格等(不过资源商店有一个Animation Instacing: 链接)

(补充:Unity官方开源了一个Animation Instacing: https://blogs.unity3d.com/cn/2018/04/16/animation-instancing-instancing-for-skinnedmeshrenderer/)

这些支持信息在官网的页面都有罗列 https://docs.unity3d.com/Manual/GPUInstancing.html

硬件需求:

GPU Instancing is available on the following platforms and APIs:

  • DirectX 11 and DirectX 12 on Windows

  • OpenGL Core 4.1+/ES3.0+ on Windows, macOS, Linux, iOS and Android

  • Metal on macOS and iOS

  • Vulkan on Windows and Android

  • PlayStation 4 and Xbox One

  • WebGL (requires WebGL 2.0 API)

模块间的需求(没找到原版的帖子,翻译版摘抄一段):

下列情况不能使用Instancing:

  • 使用Lightmap的物体
  • 受不同Light Probe / Reflection Probe影响的物体
  • 使用包含多个Pass的Shader的物体,只有第一个Pass可以Instancing前向渲染时,受多个光源影响的物体只有Base Pass可以instancing,Add Passes不行

另外,默认的DrawMeshInstanced有1024实例数的限制

需要DrawMeshInstancedIndirect,而这个接口依赖ComputerShader,一些平台不支持。

然后再测一下GPU Instanced Indirect,也就是DrawMeshInstancedIndirect这个接口

似乎是借助ComputerShader实现超过1024数量的Instancing

下图为3万个Cube:

代码和shader我做了点修改,大致如下:

  1. void Update()
  2. {
  3. // Update starting position buffer
  4. if (cachedInstanceCount != instanceCount) UpdateBuffers();
  5.  
  6. for (int i = ; i < mPositions.Length; i++)
  7. {
  8. float angle = Random.Range(0.0f, Mathf.PI * 2.0f);
  9. float distance = Random.Range(20.0f, 100.0f);
  10. float height = Random.Range(-2.0f, 2.0f);
  11. float size = Random.Range(0.05f, 0.25f);
  12. mPositions[i] = new Vector4(Mathf.Sin(angle) * distance, height, Mathf.Cos(angle) * distance, size);
  13. }
  14.  
  15. positionBuffer.SetData(mPositions);
  16. instanceMaterial.SetBuffer("positionBuffer", positionBuffer);
  17.  
  18. // Render
  19. Graphics.DrawMeshInstancedIndirect(
  20. instanceMesh,
  21. ,
  22. instanceMaterial,
  23. new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)),
  24. argsBuffer);
  25. }

shader需要额外定制,这点比较蛋疼。如果换成standard读不到positionBuffer这种结构。

DrawMeshInstancedIndirect的具体使用案例,可以参考这两个链接:

https://docs.unity3d.com/ScriptReference/Graphics.DrawMeshInstancedIndirect.html

https://github.com/tiiago11/Unity-InstancedIndirectExamples

补充测试工程地址https://gitee.com/Hont/GPUInstancingTest

(unity2017.4)

扩展阅读:

Geometry instancing

https://en.wikipedia.org/wiki/Geometry_instancing

Unity中的批处理优化与GPU Instancing

http://forum.china.unity3d.com/thread-22714-1-3.html

Unity GPU Instancing的使用尝试的更多相关文章

  1. cocos2dx 实现gpu instancing

    所有的gpu instancing都是在unity3d上实现的,ue4实现起来应该压力也不大相关链接见下:https://www.cnblogs.com/hont/p/7143626.htmlhttp ...

  2. [unity]GPU Instance学习

    前言我们之前研究过为什么Unity的UI可以合批,是因为使用了相同的材质进行渲染,UI上不同图片渲染是通过把图片打成一张图集后,使用Image组件对顶点填充了不同的UV值实现的.那么有没有什么办法可以 ...

  3. Unity GPU Query OpenGLES 3.0

    https://github.com/google/render-timing-for-unity/blob/master/RenderTimingPlugin/RenderTimingPlugin. ...

  4. unity GPU bound or CPU bound

    unity判断GPU CPUbound android 用unity profiler 里面的cpu时间 xcode有直接的显示

  5. Unity ML-agents 一、初次尝试

    前言 曾在高二寒假的时候,跟表哥在外面玩,当时他问我有没有想过以后要做什么,我愣了一下,回答不上来.是的,从没想过以后要做什么,只是一直在完成学校.老师安排的任务,于是那之后半年,我一直在思考,大学要 ...

  6. GPU instancing

    参考 https://www.cnblogs.com/hont/p/7143626.html github地址 https://github.com/yingsz/instancing/ 补充2点: ...

  7. Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译

    本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...

  8. Unity优化方向——优化Unity游戏中的图形渲染(译)

    CPU bound:CPU性能边界,是指CPU计算时一直处于占用率很高的情况. GPU bound:GPU性能边界,同样的是指GPU计算时一直处于占用率很高的情况. 原文:https://unity3 ...

  9. UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇

    报告目录: 一.ARPG手游总体性能开销分析 二.ARPG手游CPU模块性能开销分析 三.ARPG手游内存模块性能开销分析 四.ARPG手游资源管理分析 五.UWA对于ARPG手游研发团队的建议 一. ...

随机推荐

  1. 使用VS2015开发asp程序让IIS express 允许的父路径的方法

    一.Win7更好修改下面地址的文件: C:\Program Files (x86)\IIS Express\config\schema或C:\Program Files\IIS Express\con ...

  2. Selenium Page object Pattern usage

    使用Selenium的framework,大家免不了要使用他的page object pattern来开发适合自己的framework,原因很简单,page object 可以将测试的对象抽象成一个个 ...

  3. Echarts折线图点击事件

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  4. Aggressive cows

    总时间限制: 1000ms 内存限制: 65536kB 描述 Farmer John has built a new long barn, with N (2 <= N <= 100,00 ...

  5. C# 向指定的进程发送消息

    public static class ProcessExtensions { // Messages const int WM_KEYDOWN = 0x100; const int WM_KEYUP ...

  6. HDU 2217 Data Structure?

    C - Data Structure? Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u ...

  7. VS2017写的exe调用Delphi 7写的DLL

    公司有个很古老的系统,代码量很大,并且稳定线上运行10几年,这系统是公司的核心,公司收入基本靠它,系统几乎都是Delphi 7写的,要重写是不可能的.因为Delphi 7编译出来的DLL默认的导出符号 ...

  8. 阿里云设置CDN加速访问OSS文件

    快速配置OSS:https://help.aliyun.com/document_detail/31885.html?spm=5176.doc31886.6.97.8iuJo5 快速配置CDN:htt ...

  9. Map遍历的几种方法

    查看Map自带API map遍历方法: public static void main(String[] args) { Map<Integer,String> map = new Has ...

  10. (原)ubuntnu中anaconda的g++提示crtbeginS.o:unrecognized relocation

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6950263.html 自从使用anaconda后,方便是方便了,也遇到了很多蛋疼的问题. 这次使用an ...