Unity GPU Instancing的使用尝试
似乎是在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
Unity GPU Instancing的使用尝试的更多相关文章
- cocos2dx 实现gpu instancing
所有的gpu instancing都是在unity3d上实现的,ue4实现起来应该压力也不大相关链接见下:https://www.cnblogs.com/hont/p/7143626.htmlhttp ...
- [unity]GPU Instance学习
前言我们之前研究过为什么Unity的UI可以合批,是因为使用了相同的材质进行渲染,UI上不同图片渲染是通过把图片打成一张图集后,使用Image组件对顶点填充了不同的UV值实现的.那么有没有什么办法可以 ...
- Unity GPU Query OpenGLES 3.0
https://github.com/google/render-timing-for-unity/blob/master/RenderTimingPlugin/RenderTimingPlugin. ...
- unity GPU bound or CPU bound
unity判断GPU CPUbound android 用unity profiler 里面的cpu时间 xcode有直接的显示
- Unity ML-agents 一、初次尝试
前言 曾在高二寒假的时候,跟表哥在外面玩,当时他问我有没有想过以后要做什么,我愣了一下,回答不上来.是的,从没想过以后要做什么,只是一直在完成学校.老师安排的任务,于是那之后半年,我一直在思考,大学要 ...
- GPU instancing
参考 https://www.cnblogs.com/hont/p/7143626.html github地址 https://github.com/yingsz/instancing/ 补充2点: ...
- Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译
本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
- Unity优化方向——优化Unity游戏中的图形渲染(译)
CPU bound:CPU性能边界,是指CPU计算时一直处于占用率很高的情况. GPU bound:GPU性能边界,同样的是指GPU计算时一直处于占用率很高的情况. 原文:https://unity3 ...
- UWA发布 | 2017 Unity手游体检蓝皮书 — ARPG篇
报告目录: 一.ARPG手游总体性能开销分析 二.ARPG手游CPU模块性能开销分析 三.ARPG手游内存模块性能开销分析 四.ARPG手游资源管理分析 五.UWA对于ARPG手游研发团队的建议 一. ...
随机推荐
- 《Android源代码设计模式解析与实战》读书笔记(十)
第十章.解释器模式 解释器模式是一种用的比較少的行为型模式.其提供了一种解释语言的语法或表达式的方式. 可是它的使用场景确实非常广泛,仅仅是由于我们自己非常少回去构造一个语言的文法,所以使用较少. 1 ...
- LR接口性能测试提示Code - 60990 Error: Two Way Communication Error: Function two_way_comm_post_message / two_ (转载)
一.在做JAVA接口性能测试时,场景在运行中出现:Code - 60990 Error: Two Way Communication Error: Function two_way_comm_post ...
- 这是一篇满载真诚的微信小程序开发干货
1月9日零点刚过,张小龙与团队正式发布微信小程序.它究竟能在微信8.5亿用户中牵动多少人,现在还很难说.但对于创业者来讲,小程序无疑带来了新契机,以及服务“上帝”们的新方式. 从今天起,只要开发者登录 ...
- 【win7 + win server 2008】设置定时任务,设置.bat 文件去执行php脚本 == 用来配合爬虫程序简直不要太爽
Windows Server 2008中使用计划任务定时执行BAT bat进行PHP脚本的执行 一.首先进行任务管理器设置 每隔1分钟执行.BAT 文件配置 首先Windows Server 200 ...
- ios中封装九宫格的使用(二级导航)
效果图 一般用于导航功能 第一步下载http://pan.baidu.com/share/link?shareid=1824940819&uk=923776187 第二步 把下图内容放在你的x ...
- CentOS设置开机自动启动某服务
CentOS设置开机自动启动某服务 这里以启动sshd服务为例: 查看sshd是否已经是系统服务: # chkconfig --list |grep sshd 会显示: sshd ...
- 使用perf + FlameGraph生成进程火焰图
FlameGraph代码:https://github.com/cobblau/FlameGraph 使用方法 1,perf record --call-graph dwarf -p 12345 2, ...
- 【虚拟化系列】VMware vSphere 5.1 简介与安装
一. VMware vSphere 5.1简介 vSphere是VMware推出的基于云计算的新一代数据中心虚拟化套件,提供了虚拟化基础架构.高可用性.集中管理.监控等一整套解决方 ...
- 【Android】Android实现Handler异步详解
方式不止一种,这里使用的是Timer类,创建一个定时器.我们经常需要获得移动设备端口的显示屏信息,但是onCreate()方法执行的时候,OnShow()方法不一定执行了,也就是说,在执行Oncrea ...
- 【Servlet】Java Serlvet Listener 监听器
Listener监听器 Servlet规范中定义的一种特殊的组件,用来监听Servlet容器产生的事件并进行相应的处理 容器产生的事件分类 - 生命周期相关的事件 - 设置和删除Attribute数据 ...