帧同步框架下的浮点数精度计算

帧同步框架下的浮点数精度计算

本期我们聚集了这几个话题:帧同步框架下游戏逻辑的浮点数精度问题;引用相同材质, 但DrawCall合批的结果不一致、Pragma Target 3.0、GC的标准...


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

UWA 问答社区:answer.uwa4d.com
UWA QQ群:793972859(原群已满员)


帧同步

Q1:我们游戏采用帧同步框架,计算逻辑的时候不可避免地产生浮点数运算,如移动和跳跃等。为了保证在不同的平台和不同的机器上得到一致的结果,有什么好的方案能解决或避免浮点数结果不一致的问题呢?

A1:一般情况下,浮点计算涉及到的位置同步无需保留过高的精度,小数点后保留2位到4位足矣。因此计算前将浮点数乘以1000,然后取整再进行计算,可以有效地解决多端的精度不同步问题。但是需要注意一个问题,就是别超出了你数值类型的最大值范围。
感谢odiecc@UWA问答社区提供了回答

A2:根据我们自己正在摸索的帧同步经验,如果不是王者荣耀这种级别的游戏,帧同步的浮点数精度影响不是系统的瓶颈。如果战斗时长不长,露馅的概率很低,全改整数的工作量是非常巨大。如果是小公司,要好好评估是否能挺住。逻辑与表现的分离才是最大的问题,意味着Unity的大量组件不能使用。大量的重新实现的东西需要从头去写,当然全用整数也一样得重头去写。游戏小公司需慎重评估生存问题和完美方案的性价比。
感谢李先生@UWA问答社区提供了回答

A3:帧同步还是定点数比较靠谱,浮点数带来的误差有可能累计到一个无法接受的地步。另外回答其他朋友的一些问题。
1)网络传输,使用可靠的UDP(TCP)传输;
2)另外看到其他朋友提到的逻辑与表现的分离,这个是帧同步方案必须的,至于说到的Unity中大量组件组件无法使用,主要是> > 帧同步方案逻辑的处理不应该按照本地时钟时序,而是严格按照服务器逻辑帧处理,说不可用其实主要针对逻辑层而言,表现层其实不见得Unity组件都不可以用,表现层上Unity的组件其实必不可少的。
感谢Chale@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/59488b5a252497237a7c3f9e


渲染

Q2:在Shader的Pass中添加"LightMode" = “ShadowCaster”,即表示为此物体添加了投影与深度渲染的功能,但是当我把"LightMode" = "ShadowCaster"移除后,并且Fallback为off的情况下,烘焙(灯光选为Bake,不是Mixed)这个对象,竟然可以产生出阴影来,这是为什么呢?

ShadowCaster仅仅是用于动态阴影中(Cascaded ShadowMap),而烘焙是不会使用这个LightMode的。

烘焙会使用到Meta这个LightMode,可以参考:
https://docs.unity3d.com/Manual/MetaPass.html

因为烘焙阴影是完全由Enlighten计算,从一般的光线跟踪烘焙实现来说,是否投影取决于物体的mesh以及透明度,如无意外的话meta产生的透明度信息会被用于Enlighten中,而没有必要使用ShadowCaster来产生额外的信息给Enlighten使用。
如果只是为了屏蔽阴影的话,可以考虑用脚本做,给物件挂上,然后用脚本烘焙,发现有这个脚本的物件都关闭阴影,烘焙后再还原就好了。

感谢招文勇@UWA问答社区提供了回答,欢迎转至社区交流:
https://answer.uwa4d.com/question/5b8106381e88b37d34e6536c


渲染

Q3:某个Shader中添加了如下指令:

#pragma target 3.0
那么当此Shader在不支持此特性时,会自动Fallback到Pragma Target 2.0吗?

A1:https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html


When writing either Surface Shaders or regular Shader Programs, the HLSL source can be compiled into different “shader models”. To allow the use of more modern GPI functionality, you must use higher shader compilation targets.

Note: Using higher shader compilation targets may prevent the shader from working on older GPUs or platforms.

题主可以自己理解下,我的理解和体会是,如果不支持的指令或者特性,不会FallBack,会直接粉红。
感谢贾伟昊@UWA问答社区提供了回答

A2:贴上之前一个问题的回答:关于工程里的 Graphics API 的选择问题
Shader Target其实本身就是一个由Unity抽象出来的概念(或者说是参照DX的Shader Model抽象出来的概念),实则对应的是Graphics API。它同样不仅代表了API的变化,也代表了硬件能力的提升。
你要使用Shader Target 3.0的Vertex Texture Sampling,就别指望Unity帮你在Shader Target 2.0的机器上自动转换成Pixel Texture Sampling了。
当然,最好的办法就是自己指定了FallBack。
感谢凯奥斯@UWA问答社区提供了回答

该问答来自UWA问答社区,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5b88e0cf339d267d357c6e69


GC

Q4:我们现在写的程序跑的是什么版本的GC?我之前一直把C#的那套GC原理作为我们现在写的程序的GC标准,今天突然看到官方文档上说Unity有自己的GC,然后就很迷惑了,以下问题求告知:
1)Unity的GC就是Mono的GC吗?
2)Mono不是实现.NET标准的么?
3)那么Mono的GC,不应该也是C#的GC原理么?

A1:CLR的GC有三代,Mono或IL2CPP的GC是不分代的。
Mono源码:https://github.com/mono/mono
Mono现在用的GC是Benchmark Suite:https://github.com/xamarin/benchmarker
当然你或许也可以自己编mono库,使用多代多线程GC,SGen
https://www.mono-project.com/docs/advanced/garbage-collector/sgen
感谢凯奥斯@UWA问答社区提供了回答

A2:1)Mono早期使用的是Boehm-Demers-Wiser GC库,后期更新为有分代和多线程能力的SGen库。
2)这里需要强调一下,由于历史原因,Unity使用版本比较老的Mono,然后在其基础上做了很多修改,以及整合外围的一些新功能,导致的结果是无法跟进最新版本的Mono,这也是为什么GC还是最老的Boehm-Demers-Wiser库。所以如果想自己尝试整合最新的Mono,很可能会不理想。
3)然后,还不能忘了IL2CPP,这是完全独立的一个Runtime,编译成IL2CPP就意味着跟Mono没有关系了,这时它也有自己的一套GC实现,很不幸依然使用了老旧的Boehm-Demers-Wiser GC。
4)Mono在语法、编译、Runtime、库等等层面上确实执行了.NET的标准,但是GC的底层实现上至少早期是没有明确规定怎么实现底层的,就算有,Mono也因为微软不公开代码的原因,当时也不得不自己摸索一套方案,于是也就有了现在跟.NET毫无关联的GC实现。
感谢招文勇@UWA问答社区提供了回答

该回答由UWA提供,欢迎大家转至社区进一步交流:
https://answer.uwa4d.com/question/5b7bc2d71e88b37d34e65337


渲染

Q5:请教个问题, 游戏场景在部件都加载完成之后,对需要静态合批的部件,统一执行一次 StaticBatchingUtility.Combine,我发现在游戏中合批的效果跟直接在场景中合批 DrawCall差别很多。
请输入图片描述
这些Model都合批成功, 都是这个。
请输入图片描述
引用相同材质, 材质变量一样,实例化出来材质ID也一样。两个DrawCall模型中的Mesh也看到合批了, 但是就是两次提交, 两个DrawCall,而不是1个DrawCall。
我不是很明白,到底是哪里出问题。我们在场景中执行执行静态合批之后,场景DrawCall大概40左右,在游戏中加载完场景执行一次静态合批, DrawCall大概110左右。

经排查发现这个问题是由无法静态合批所致, 提示“Objects are affected by different forward lights”。经进一步测试,发现差异点为在游戏中,场景部件受到点光源照射, ForwardAdd打断合批过程, 如果把点光源屏蔽掉, 能够正常合批。

感谢题主分享了该问答并提供了解决方案,欢迎大家转至社区进一步交流:
https://answer.uwa4d.com/question/5b87c9fc339d267d357c6e5b

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

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
官方技术QQ群:793972859(原群已满员)