【厚积薄发】帧同步框架下的浮点数精度计算

2023-10-27 22:10

本文主要是介绍【厚积薄发】帧同步框架下的浮点数精度计算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

UWA 问答社区:answer.uwa4d.com

UWA QQ群:465082844(仅限技术交流)

 

帧同步

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

 

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

 

渲染

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

 

A: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

 

渲染

Q:某个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

Q:我们现在写的程序跑的是什么版本的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

 

渲染

Q:请教个问题, 游戏场景在部件都加载完成之后,对需要静态合批的部件,统一执行一次 StaticBatchingUtility.Combine,我发现在游戏中合批的效果跟直接在场景中合批 DrawCall差别很多。

这些Model都合批成功, 都是这个。

引用相同材质, 材质变量一样,实例化出来材质ID也一样。两个DrawCall模型中的Mesh也看到合批了, 但是就是两次提交, 两个DrawCall,而不是1个DrawCall。

我不是很明白,到底是哪里出问题。我们在场景中执行执行静态合批之后,场景DrawCall大概40左右,在游戏中加载完场景执行一次静态合批, DrawCall大概110左右。

 

A:经排查发现这个问题是由无法静态合批所致, 提示“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群:465082844(仅限技术交流)

近期重磅 | 快来看看业界手游性能呈几何

 

这篇关于【厚积薄发】帧同步框架下的浮点数精度计算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/288720

相关文章

Python实现精确小数计算的完全指南

《Python实现精确小数计算的完全指南》在金融计算、科学实验和工程领域,浮点数精度问题一直是开发者面临的重大挑战,本文将深入解析Python精确小数计算技术体系,感兴趣的小伙伴可以了解一下... 目录引言:小数精度问题的核心挑战一、浮点数精度问题分析1.1 浮点数精度陷阱1.2 浮点数误差来源二、基础解决

GSON框架下将百度天气JSON数据转JavaBean

《GSON框架下将百度天气JSON数据转JavaBean》这篇文章主要为大家详细介绍了如何在GSON框架下实现将百度天气JSON数据转JavaBean,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言一、百度天气jsON1、请求参数2、返回参数3、属性映射二、GSON属性映射实战1、类对象映

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Python文本相似度计算的方法大全

《Python文本相似度计算的方法大全》文本相似度是指两个文本在内容、结构或语义上的相近程度,通常用0到1之间的数值表示,0表示完全不同,1表示完全相同,本文将深入解析多种文本相似度计算方法,帮助您选... 目录前言什么是文本相似度?1. Levenshtein 距离(编辑距离)核心公式实现示例2. Jac

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Python中经纬度距离计算的实现方式

《Python中经纬度距离计算的实现方式》文章介绍Python中计算经纬度距离的方法及中国加密坐标系转换工具,主要方法包括geopy(Vincenty/Karney)、Haversine、pyproj... 目录一、基本方法1. 使用geopy库(推荐)2. 手动实现 Haversine 公式3. 使用py

解决若依微服务框架启动报错的问题

《解决若依微服务框架启动报错的问题》Invalidboundstatement错误通常由MyBatis映射文件未正确加载或Nacos配置未读取导致,需检查XML的namespace与方法ID是否匹配,... 目录ruoyi-system模块报错报错详情nacos文件目录总结ruoyi-systnGLNYpe

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1