一.关于GPUInstance
1.用于渲染加速的硬件特性.
gpu硬件支持的一种特性,使用少量的渲染调用(DrawCall)渲染同一网格的多个副本.也就是说在渲染时,他只需要提交一个网格副本,一个材质球,然后在把这些模型对象中不同的属性(比如:位置,大小,旋转,颜色等)提取出来放到一个数组中.
2.底层逻辑,为什么能够加速渲染,提高性能?
- 针对同网格同材质的模型多个对象进行渲染时,有一下几种渲染方式:
- 原始模式,每个材质和模型都调用一次渲染,这样会导致的后果是,每次渲染一个对象CPU就会向GPU提交一次渲染相关的所有资源.很明显这里面有很多重复资源的提交造成了很大的浪费,也让渲染速度大大降低.
- 动态合批模式,这个很好,把最近相同的模型进行合并成一个模型,然后一次提交一次渲染,爽快利落,典型的空间换速度,也很划算,最大化的提高渲染效率.但是,当网格数量和网格的顶点数超过一定数量时,动态合批就不能在进行了因为这个时候就会拉低CPU的执行效率,以及内存空间的暴涨.所以动态合批有较多的限制.
- 静态合批模式,这个也很好,离线把模型全部给合并到一个网格(合并后的网格顶点数量有限制:65535),这样能够解决动态合批的问题,但是也有问题,会导致一下几个问题:
- 重复网格的副本会被复制很多份,导致资源包体和运行时内存都会有很大的增长.
- 一些不需要渲染的顶点也被提交给GPU,增大了GPU的顶点处理器的压力,.
- 在逻辑处理上,静态合批也有一个问题,就是合并完后的模型对象不能再被位移,旋转,缩放等处理了.
- 然后就是GPUInstance,他也是针对相同模型的网格和材质只提交一次,然后他组合这些模型对象的不同之处打成一个数组提交给GPU,这样既能够减少提交的次数,有不会让内存暴涨.CPU端也不会因为合并网格而各种计算,增加消耗.这样他的特点就出来了:
- 在CPU端进行模型裁剪,只合并看见的模型对象.这样提交给GPU渲染的实例会更少更有效.在某些场景下,这个相对于静态批处理来说优势很足.
- 只组织和提交模型对象之间的不同之处,内存的消耗也能够控制.这个相对于动静两种合批来说都是优势巨大.
- 不需要做网格的合并处理,这方面也CPU没有消耗.这个相对于动态合批来说优势巨大.
- 在CPU端的实例不同点的合并处理,需要一定的消耗,这个对于静态批处理来说没有优势.
- 在GPU端要增加一个索引和缓存的读取处理,这个也算是额外的消耗,这个对于静态批处理和动态批处理都没有优势.
- 因为一个批量渲染,只提交一个网格副本,所以对于网格的大小就没有了限制.适应范围更广泛,这个对于动态合批来说优势巨大.
- 综上几个渲染方式的对比之后,在针对这种大量的同网格,.同材质的模型时,数量越大性能提高程度就越明显.
二.适用场景
1.不能被动态合批
模型顶点数据(位置,法线,切线,UV等)总和不能超过2700个float.
2.静态合批不划算或者不能静态核批
模型为一簇簇的出现或者散布广泛
模型对象位置,大小,旋转等都在变化.
比如:
草丛,树木丛
建筑装饰物件
陨石群
三.在U3D里实现
Shader的支持
基础使用
1).使用U3D内置的Shader
- 使用Unity自带的能够开启GpuInstance 的Shader(几乎都有,但是也有例外,比如Partcles的材质好像都没有.),创建一个材质球.
- 在材质球的Inspector中把Enable GPU Instancing的选项给勾选上.