似乎是在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一次性调用减少了层级对象的创建开销):

void Update()
{
var meshRenderer = template.GetComponent<MeshRenderer>();
var meshFilter = template.GetComponent<MeshFilter>();
var mesh = meshFilter.sharedMesh;
var matrices = new Matrix4x4[instanceCount]; for (int i = ; i < matrices.Length; i++)
{
var position = Random.insideUnitSphere * range;
var rotation = Quaternion.LookRotation(Random.insideUnitSphere);
var scale = Vector3.one * Random.Range(-2f, 2f);
var matrix = Matrix4x4.TRS(position, rotation, scale); matrices[i] = matrix;
} Graphics.DrawMeshInstanced(mesh, , meshRenderer.sharedMaterial, matrices);
}

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

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

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

大概在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我做了点修改,大致如下:

void Update()
{
// Update starting position buffer
if (cachedInstanceCount != instanceCount) UpdateBuffers(); for (int i = ; i < mPositions.Length; i++)
{
float angle = Random.Range(0.0f, Mathf.PI * 2.0f);
float distance = Random.Range(20.0f, 100.0f);
float height = Random.Range(-2.0f, 2.0f);
float size = Random.Range(0.05f, 0.25f);
mPositions[i] = new Vector4(Mathf.Sin(angle) * distance, height, Mathf.Cos(angle) * distance, size);
} positionBuffer.SetData(mPositions);
instanceMaterial.SetBuffer("positionBuffer", positionBuffer); // Render
Graphics.DrawMeshInstancedIndirect(
instanceMesh,
,
instanceMaterial,
new Bounds(Vector3.zero, new Vector3(100.0f, 100.0f, 100.0f)),
argsBuffer);
}

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

最新文章

  1. 通过Mono 在 Heroku 上运行 .NET 应用
  2. Service之三种服务方式
  3. apt-get install *** 出现 软件包***没有提供可供安装的候选者
  4. Leetcode4:Median of Two Sorted Arrays@Python
  5. 运维利器-ClusterShell集群管理操作记录
  6. 学习SQL的点点滴滴(三)-修改数据库的兼容级别
  7. maven nexus deploy方式以及相关注意事项
  8. php编译报错 configure: error: Please reinstall the libcurl distribution - easy.h should be in &lt;curl-dir&gt;/include/curl/
  9. 在 Server 端存取 Excel 檔案的利器:NPOI Library
  10. NSMutableAttributedString 设置不同颜色,不同字体的String
  11. CentOS 关闭蜂鸣
  12. C#封装加密算法(MD5、SHA、HMAC、DES、RSA)的一个类
  13. Win7/Win8/Win8.1众多版本,我该选择哪个?
  14. Linux磁盘分区,目录树,文件系统的关系(转)
  15. 如何在Shell中快速切换目录
  16. css动画--元素上下跳动
  17. 享元模式 FlyWeight 结构型 设计模式(十五)
  18. Python母版使用
  19. video自动禁止全屏
  20. 002.Docker安装部署

热门文章

  1. minimum-path-sum-动态规划
  2. 背景图片自适应整个页面CSS+DIV
  3. Oracle Data Integrator 12cR1 (12.1.3.0.0)安装过程
  4. fiddler怎么修改服务器返回参数并发送
  5. 微软微服务架构eShopOnContainers
  6. windows DLL中使用COM的注意事项
  7. java struts2入门学习实例--使用struts2快速实现多个文件上传
  8. kubelet源码分析(version: git tag 1.7.6)
  9. C# winform DataGridView 常见属性
  10. Windows Hadoop Error: JAVA_HOME is incorrectly set.