[david]unity3d绘制调用批处理(draw call batching)
来源:互联网 发布:ps盖印图层快捷键 mac 编辑:程序博客网 时间:2024/06/07 23:57
要绘制一个gameobject到屏幕上,unity需要调用图像api(dx,opengl)。
图像api对每一个绘制请求都需要做大量的工作,例如输入资源校验,顶点空间信息转换。
特别是在切换不同材质球的时候,图形api要做的工作更多,因为要切换状态(透明,不透明,贴图输入,渲染方式,加载shader,调用gpu驱动api前,获取/组织/封装输入参数)。
而图形api(dx,opengl)是在cpu上运行的,所以draw call的调用会增加cpu负载,消耗cpu时间
(unity--draw call-->dx/opengl || CPU || -->显卡驱动|| GPU ||);
优化思路:减少draw call 数量,减少状态切换
每个mesh,每个材质,每个pass 都会产生一个draw call调用。
所以,最有效的方法是合并mesh来减少draw call数量。
unity有内置(好处:引擎代码层面可以独立控制每个物体)的两种合并mesh技术:
A:针对足够小的动态网格体,使用动态批处理(Dynamic batching),把类似的顶点分组,一次绘制。
限制:1、shader中最多使用900个顶点属性(例如:vert函数输出中有vertex position,normal,uv三个属性,那么输入网格最多能有300个顶点,才能加入到动态批处理)(动态批处理的每个顶点都有开销)
2、空间上存在镜像的多个物体不能一起使用动态批处理(例如:A物体的Transform_scale_x是1,B物体的Transform_scale_x是-1)
3、使用不同的材质实例不能动态批处理,即使是同一材质的不同实例,原因是阴影投射渲染的异常?
4、有附加渲染参数(lightmap index offset/scale)的光照贴图游戏物体。通常动态光照贴图游戏物体应该指向定位在批处理里的相同光照贴图?
5、多pass shader不能批处理。
在前向(forward rendering)渲染模式中,unity shader 支持多灯光,附加像素光源对应的pass不能批处理。
传统的延后(defferred(light pre-pass))渲染不支持批处理,因为延后渲染要绘制物体两次。
动态批处理要在CPU上将游戏物体的所有顶点变换到世界空间。这样变换的开销比图形api(dx,opengl)执行draw call的开销更小才有意义。
draw call要求的资源受很多因素影响,主要是dx/opengl api使用的资源。例如:主机或苹果平台上draw call的开销较小,动态批处理没有什么优势。
B:针对静态物体,合并成一个大网格体,叫静态批处理(static batching)
静态批处理会增加内存消耗。即使批处理前共享网格的N个物体,也会增加N-1份内存消耗。
例如:茂密的树林,标记为静态,使用静态批处理,就会有大量的内存消耗。这时可以考虑不标记为静态,消耗时间,节省内存开销
处理过程:将静态游戏物体转换到世界空间,
创建一个大的顶点集(64K 顶点数 )和索引缓存(64K 索引数(48K opengles,32K macos));
然后,对同意批次中的可见游戏对象,执行一系列简单的,几乎没有状态切换的draw call。
技术上没有减少draw call 数量,当大量减少了状态切换(dx/opengl重大开销的部分);
这两种批处理技术能够减少的draw call数的一个重要因素是:合并的物体共享材质的程度。
因为,不同材质不可能使用同一个draw call(排除阴影绘制)
只有共享材质的多个物体,合并成一个大网格体后,才能显著降低draw call数。
例如,10个共享材质(1个pass)的静态物体
没有使用静态批处理是10个draw call;
使用后为1个draw call,降低了90%的draw call 数。
可使用批处理的渲染器:Mesh Renderers,Trail Renderers,Line Renderers,PaticleSystems,Sprite Renderers
不能使用批处理的渲染器:skinned Meshes,cloth,other
只有同类型的渲染器可以批处理。
半透明物体比不透明物体更少的机会使用批处理,因为要从后到前的顺序获取半透明物体(确保透明效果),然后才批处理,顺序严格,获得批处理的机会更少。
通过3d模型软件或Mesh.CombineMeshes手动合并相邻的网格物体是一个替换批处理的好方法。
例如一个有多个绘制器的静态碗柜合并成一个网格是好的。
结论:多个物体共享材质(合并贴图,shader减少pass,少分支判断语句),多标为静态物体,是有效减少draw call,state changes,进而减少图形api(dx,opengl)/CPU负载,同时降低GPU负载的有效途径。
阅读全文
0 0
- [david]unity3d绘制调用批处理(draw call batching)
- unity3d Draw Call Batching (绘制调用批处理)
- Draw Call Batching (绘制调用批处理)
- unity项目优化--绘制调用批处理unity3d Draw Call Batching
- Unity3D优化之Draw Call Batching
- Unity3D性能优化之Draw Call Batching
- Unity3D优化之Draw Call Batching
- Unity3D项目优化--绘制调用批处理unity3D Draw
- Draw Call Batching
- Draw Call Batching
- Draw Call Batching介绍
- U3D Draw call batching
- Unity Draw call batching 动态合并(2017.2.0版本Unity)
- Unity3D教程:优化Draw Call
- Unity3D技术之优化图形性能绘制调用批处理浅析
- Unity3D技术之优化图形性能绘制调用批处理浅析
- Unity3D - 图形性能优化:批量draw call
- Unity3D - 性能优化之Draw Call
- xampp/wamp集成环境安装后,如何修改mysql的默认编码格式的方法整理
- Maven认知
- laravel框架的{{asset}}和{{url}}有什么区别
- RTP/RTCP&RTSP 的关系
- Linux 下设置IP、网关、DNS
- [david]unity3d绘制调用批处理(draw call batching)
- ArcGIS API for JavaScript 实现point multipoint line polyline cirle等graphics的绘制
- 使用 Spring Boot 快速构建 Spring 框架应用
- 环信笔记
- OpenGL实现Hermite算法绘制三次曲线
- 教您用数学课件制作工具画椭圆
- 大众点评接口优惠卷,订单对接
- myeclipse一直Building workspace
- Linux ALSA声卡驱动之一:ALSA架构简介