不同种Mesh的DrawCall优化策略

栏目: 后端 · 发布时间: 6年前

内容简介:这是第156篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。UWA 问答社区:answer.uwa4d.comUWA QQ群2:793972859(原群已满员)

这是第156篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com

UWA QQ群2:793972859(原群已满员)

本期目录:

  • 不同种Mesh的DrawCall优化策略
  • AnimationClip内存优化
  • 渲染效果出错
  • Unity编译后报错是否有回调可用
  • UGUI图集排列问题

DrawCall

Q:我在制作一款Voxel的游戏,目前游戏内:所有模型均公用同一个Material,每个模型部件(怪)都是单独的Mesh,用Animator制作的动画无骨骼,就是关键帧动画,已开GPU Instance。

遇到的问题:
比如一个角色有10+个部件,当地图上同时出现10种怪时候,模型部分的DrawCall就会飙升到100+。因为目前特效加入不多,所以用真机测试(Mi8 Lite)时候并未出现卡顿效果,并且开了GPU Instance,在种类不多、数量多的情况下运行也良好。

但是还是想问一下各位大神,这个高DrawCall的问题,有什么好的优化方法吗? 或者说有必要优化吗?感谢!

不同种Mesh的DrawCall优化策略
不同种Mesh的DrawCall优化策略
不同种Mesh的DrawCall优化策略

A:自己做Culling+手动调用DrawMeshInstanced(直接材质勾选instance经常合不起来),可以减少到部件种类数个DrawCall。

对动画精度要求不高又肯空间换时间,整个模型按帧动画bake出来,用DrawMeshInstanced可以缩减到模型种类数个DrawCall。

用LWRP/HDRP有个懒人福利,把SRP batcher打开,材质不要(注意是不要)勾选enable instance,如果用的是内置Shader,直接可以看到DrawCall骤减,自定义Shader改写一下也不难。

感谢Nil@UWA问答社区提供了回答,欢迎大家转至社区交流: https://answer.uwa4d.com/question/5cb8ca65e08a260abaf02053

Animation

Q:有什么好的方法可以优化动画内存占用?除了常见的降低精度、压缩、去Scale等操作外,降低frame Rate是否可行?

A1:关于frame Rate可以补充一下:

如果题主问的是动画导入到Unity后,在播放时改变frame Rate(通过控制动画播放speed,导入Unity后实际已经没法改变动画片段原始frame Rate了),那frame Rate的改变不会影响内存;

但是,如果题主指的是在动画制作软件里(比如3ds Max、Maya)修改frame Rate,那导入到Unity后内存确实会受些影响。此时,如果两个动画一致,单纯frame Rate不同:

1、不开动画压缩时,实际关键帧数多的片段(通常是frame Rate高的),内存会大一些,而且还有几个影响因素:

a、导入时开启resample curves(该选项决定Unity在导入时是否自动插帧,会使所有曲线在播放时间段满帧),那frame Rate高的内存会高很多;

b、不开resample,那frame Rate高的会高一点。

2、开动画压缩时,比如Keyframe Reduction,不同frame Rate的内存再次变得相近(因为动画一致,实际动画曲线也类似,压缩时同样会压缩掉一些重复的数据)。

结论也就是说,当动画压缩选项开启的时候,制作动画时的frame Rate对内存其实影响也不大,所以不需要特意在frame Rate上做优化。

该回答由UWA提供

A2:我们可以把一些线性动画进行程序模拟,这样减少动画K帧的数据量,比如常用的iTween、DOTween插件和UWA推荐的XTween等。

感谢郑骁@UWA问答社区提供了回答,欢迎大家转至社区交流: https://answer.uwa4d.com/question/5cb856d5e08a260abaf02026

渲染

Q:在iPhone上使用Metal API,并且开启MSAA,在渲染不透明物后透明物前这个阶段(例如AfterForwardOpaque)插入任意一个CommandBuffer,会使透明队列中的物体渲染最前面,好像没有了ZTest的样子。

注:使用OpenGL ES3.0没有问题,Android平台上也没有问题。

写了一个重现的Demo,构建到iPhone上运行即可。同时开启MSAA和CommandBuffer会发现两个红色Cube永远在树的前面。关闭其中一项就没问题。

附上重现的Demo:

MASSDemo.zip

题主回答:在渲染透明物之后和不透明物之前插入一个CommandBuffer,在这个Cube里把Unity的深度贴图写入到当前FrameBuffer的DepthBuffer里就解决了。

感谢贤@UWA问答社区分享了该问答,欢迎大家转至社区交流: https://answer.uwa4d.com/question/5cb463723ded097520c24cea

Script

Q:想了解Unity在编译脚本报错时有没什么回调?或者有什么Trick可以用的呢?

A1:试一下效果:

public class CompilePostProcesser : AssetPostprocessor
{
static CompilePostProcesser() { EditorApplication.update += Update; }
// 所有编译完成之后的回调[注意小心造成递归的情况出现,也就是回调中的操作又重新引起了编译]
// 如果出现编译错误,那么这个回调不会被执行
[UnityEditor.Callbacks.DidReloadScripts]
private static void OnCompiled()
{
// Debug.ClearDeveloperConsole();
Debug.LogError(“编译成功!”);
SuccsccAction?.Invoke();
}
private static void Update()
{
if (EditorUtility.scriptCompilationFailed)
{
EditorApplication.update -= Update;
Debug.LogError(“编译失败!”);
FailAction?.Invoke();
}
}
}

感谢kaclok@UWA问答社区提供了回答

A2:Trick有一个,只是比较老了。思路是尝试Clear掉日志。而编译错误是Clear不掉的,因此可以判断出是否遇到了编译错误。

static void ClearLog()
     {
         Assembly assembly = Assembly.GetAssembly(typeof(SceneView));
         Type logEntries = assembly.GetType("UnityEditorInternal.LogEntries");
         logEntries.GetMethod("Clear").Invoke (new object (), null);

         int count = (int)logEntries.GetMethod("GetCount").Invoke(new object (), null);

         if (count > 0)
             throw new Exception("Cannot build because you have compile errors!");
     }
感谢张锐@UWA问答社区提供了回答,欢迎大家转至社区交流: https://answer.uwa4d.com/question/5cc1190f5dad710abee80429

UI

Q:Unity 5.6.6版本中进行UGUI打图集,发现空间够512x512,每张图的大小是101x101的,17张101却打成了512x1024的图集。

不同种Mesh的DrawCall优化策略
不同种Mesh的DrawCall优化策略

测试的图:

不同种Mesh的DrawCall优化策略

A1:有Padding,每边一个像素,所以大了101变成103了,512放不下了。

感谢lopezycj@UWA问答社区提供了回答

A2:Sprite atlas有一个Padding属性,最小是2像素,默认是4像素。

以2像素为例,上面那张atlas图高512,四张Texture占用的高度为:2+101+2+101+2+101+2+101=412,还剩100像素,已经塞不下纵向第五行的Texture了(何况第五行和第四行之间还有2像素的Padding)。

所以一张512x512的atlas,如果要放下5行x5列的Texture,每张Texture最大只能是100x100像素,然后还要记得设置atlas的Padding属性为2像素。

感谢厅级码农@UWA问答社区提供了回答,欢迎大家转至社区交流: https://answer.uwa4d.com/question/5cbf1d175dad710abee80409

今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com

官方技术博客:blog.uwa4d.com

官方问答社区:answer.uwa4d.com

官方技术QQ群:793972859(原群已满员)

封面图来源于网络


以上所述就是小编给大家介绍的《不同种Mesh的DrawCall优化策略》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming From The Ground Up

Programming From The Ground Up

Jonathan Bartlett / Bartlett Publishing / 2004-07-31 / USD 34.95

Programming from the Ground Up is an introduction to programming using assembly language on the Linux platform for x86 machines. It is a great book for novices who are just learning to program as wel......一起来看看 《Programming From The Ground Up》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具