游戏引擎中的物理系统

一、物理对象与形状

1.1 对象 Actor

一般来说,游戏中的对象(Actor)分为以下四类:

  • 静态对象 Static Actor
  • 动态对象 Dynamic Actor ---- 可能受到力/扭矩/冲量的影响
  • 检测器 Trigger
  • Kinematic Actor 运动学对象 ---- 忽略物理法则,由游戏逻辑直接控制(可能表现的反物理)

1.2 形状 Shape

由于真实世界中很多物体形状极其复杂,所以游戏中会先设定较为简单的对象。常见的物理对象的形状有如下:
在这里插入图片描述
每一种形状都有常用的实际游戏对象,比如Height Fields用来做地形等。
在这里插入图片描述

当我们利用这些对象去组成实际需要的物体对象时,有两个原则:

  1. 形状接近就好,不一定要完美
  2. 简单性。要尽量用简单的对象去拼接(比如尽量少用三角网格),且越少越好。

此外,一些比较重要的物理概念:

  • 质量和密度 Mass and Density
  • 质心(做载具时很重要)Center of Mass
  • 摩擦和恢复(弹性) Friction & Restitution

二、 力与运动

2.1 力 Forces

一般我们把力分成两种:

  • Force 可以理解为直接的重力、拉力、摩擦力等
  • Impulse 冲量,比如说爆炸导致的冲击力等(虽然其实冲量就是力x时间(恒力条件下))

2.2 运动 Movement

经典的定理(游戏中需要用数学表示):

牛顿第一定律 无外力 —> 匀速直线运动
在这里插入图片描述
牛顿第二定律 F = ma (质量的本质是改变物体物理状态的倾向性)
在这里插入图片描述
当这个力是恒力时:
在这里插入图片描述
当这个力是变力时:
在这里插入图片描述
其中上图中 v ( t ′ )中的 t 是二次积分(位移和时间关系公式就是二次的)

具体以圆周运动为例,如果简单去模拟物体随时间变化,并不是很困难。

但实际游戏中时间不是连续的,而是由一帧帧实现的,所以通常需要解决的问题是在已知当前物体位置和速度的前提下获取之后某时刻的物体位置和速度信息。
在这里插入图片描述

2.2.1 显示欧拉法 Explicit (Forward) Euler’s Method

最简单的估计方法,假设在这个时间片里力是恒定的

每一时刻仍按照传统的牛顿力学方法去计算:
在这里插入图片描述
这种方法下,由于实际游戏中的时间片Δt不可能和现实中一样小,所以会导致能量不守恒(变多)(如图中右侧所示,实际位移是偏多的),误差越来越大,物体逐渐甩出去。
在这里插入图片描述

2.2.2 隐式欧拉法 Implicit (Backward) Euler’s Method

与显示近似,不过将力的值和速度的值以未来(终点)为参考,如下图:
在这里插入图片描述
其中未来的值是假设能够通过解析解强行算出来的。
和显示方法类似,该方法的问题是能量会衰减,但由于这个衰减相对较慢,所以用户可能会认为是摩擦力、空气阻力等其他力的影响导致,从而使得这个衰减在游戏实际中相对不明显。
从另一个角度来说,我们在游戏引擎中设计中认为衰减肯定是好过增多的,前者顶多最后停下来,但后者会不可控会爆炸。
在这里插入图片描述

通过一系列复杂计算可以证明这种隐式方法是无条件稳定的。

但其缺点是:

  • 计算成本高(计算未来值)
  • 运动非线性时难以计算
  • 能量衰减。
2.2.3 半隐式欧拉法 Semi-implicit Euler’s Method

综合前两者的特点:
在这里插入图片描述
计算未来速度时用当前的力,计算未来位移时用未来的速度。
在这里插入图片描述

前提假设:力是不变的(很危险的假设,因为实际上力跟物体位置是相关的)。
优点是:

  • 条件性稳定
  • 计算简单有效
  • 随着时间的推移能够保存能量

缺点是:

  • 做一些sin cos等运动时,积分出来的周期会比正确值长一点点,所以在相位上会有偏移差。

三、 刚体动力学

前面所说的所有内容都是把物体看作一个质点的前提,然而事实上真实世界中大部分物体是有形状的。
一般来说,我们在引入旋转时大都针对刚体(因为柔体太难了),因为刚体就是假设物体的所有粒子之间绑定相对不动。
所以我们在刚体动力学中常常会比普通的线性计算(图中右侧)多一些概念,同一行概念有对应性:
在这里插入图片描述
具体相关概念建议看视频或讲义。

动量守恒:在宇宙中任意一个位置做实验的得到的结果是一样的–空间一致性
角动量守恒:在一个位置的任意一个方向做的实验得到的结果是一样的–朝向一致性
课外拓展:诺特定理

四、 碰撞检测

碰撞检测一般分为两个阶段:

  • Broad phase 初筛 – 利用AABB等找到刚体有没有相交
  • Narrow phase – 获取进一步信息(碰撞点、方向、深度等)

4.1 Broad Phase

一般常见的有两种方法:

BVH Tree – 更新成本低,适合动态场景。
在这里插入图片描述
在这里插入图片描述

Sort and Sweep – 先排序再逐个扫描,效率高,更符合大部分为静态物体小部分为动态物体的现实。更好。
在这里插入图片描述
在这里插入图片描述

4.2 Narrow Phase

4.2.1 Basic Shape Intersection Test

比较简单,把所有物体看作球或胶囊状去判断相交即可。

4.2.2 Minkowski Difference-based Methods

首先需要知道minkowski Sum(闵可夫斯基和)的概念,以两个三角形各自围成的点集为例,两个点集相加的结果是指所有A点集的点加上所有B点集的点,几何表示如下:
在这里插入图片描述
拓展到两个凸包也是一样道理。

然后同理,还有minkowski Difference(闵可夫斯基差)
在这里插入图片描述
简单讲就是化A-B为A+(-B)。而-B是利用对原点的对称获得。
这样一来就获得了一个很重要的结论(方法):
如果两个凸包有重叠,则它们的闵可夫斯基差必定包含原点
我们把闵可夫斯基差这些点形成的形状叫slmplex(单纯形)

由此问题转换为了如何判断两个凸包的闵可夫斯基差包含原点。
具体可查看我的文章:多边形碰撞检测算法

4.2.3 Separating Axis Theorem

如果两个物体分离,则肯定能找到空间中一根轴把它们分隔开,不然就是相交。
简单做法是把凸包A的每条边和凸包B的每条边当分隔线试试,比如对凸包A的边a,把所有顶点投影到这条边上去进行判断有没有重叠。如果所有边做分隔线都有重叠,那就是两个凸包相交。
在这个基础上,优化方法是取凸包A的某条边a做轴时,直接将凸包B的所有顶点投影到a的垂线上,因为这样可以保证凸包A的所有顶点都在垂线上a的一侧,所以只需要判断凸包B上所有顶点在垂线上的投影是否在另一侧就行。
延伸到3D空间,需要多加步骤:
在这里插入图片描述
简单讲就是如果只判断面的法线作为分隔线的可行性的话,会出现图中下面前两种情况,并误以为是两个物体相交,所以需要再加上一个检测来判断第三种情况。

五、碰撞解决

如果两个物体发生了碰撞,并且相交了怎么办?
在这里插入图片描述
最简单的早期是方法是加一个与重叠反方向的penalty force,但是会导致物体突然分隔开,很假。
现在比较合适流行的方法是利用拉格朗日力学中对速度的约束的方法。简单讲大概类似于给碰撞物体加个冲量从而影响下速度,看是不是还碰撞,不断重复直到可以接受。或者迭代次数过多不管了。
在这里插入图片描述

六、 场景请求

6.1 Raycast

通过发射一条光来判断场景中的某个点能否直接看到/射击到。

当这束光有多个撞击点时,有三种处理方式:

  • 都进行计算处理、
  • 只处理最近的、
  • any hits(不管哪个,反正有撞击就行)

6.2 Sweep

比如判断人有没有被挡住时是把人的整个胶囊体进行扫描判断的,只要有一部分被挡住就是被挡住了。

6.3 Overlap

比如判断手雷爆炸时能炸到哪些人。
在这里插入图片描述

七、 效率、准确性与确定性

  • Sleeping
    物理引擎中常把场景的不同物品或部分分成所谓不同的island,而引擎设计中很重要的一部分是让没有变化或不需要参与计算的island进入sleep,所以如何让更多island进入sleep从而减少计算量是一个关键问题。
  • Continuous Collision Detection(CCD)
    当一个快速运动的对象碰撞一个比较薄的物体时容易发生错误直接穿过去(因为前后两次计算时发现都没有碰撞,但其实不可以)
    一种比较质朴的方法就是把墙等物体做的厚一点。
    更规范的做法就是CCD:先计算一个安全时间(在这个时间内两个物体不会碰撞),然后开始一点点详细计算会不会碰撞,知道它们的距离小于一定阈值。
  • Deterministic 确定性
    游戏引擎设计时需要保证确定性,即同样的代码操作下跑起来是要尽可能一样的,而不会受那么多复杂计算和浮点问题的影响导致不同(从而在Online Gaming)中出现两方不一样的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/511526.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为审核被拒提示: 您的应用存在(最近任务列表隐藏风险活动)的行为,不符合华为应用市场审核标准

应用审核意见: 您的应用存在(最近任务列表隐藏风险活动)的行为,不符合华为应用市场审核标准。 修改建议:请参考测试结果进行修改。 请参考《审核指南》第2.19相关审核要求:https://developer.huawei.com/c…

【opencv】教程代码 —videoio(2)将两个视频的每一帧逐一读取并计算其PSNR 和MSSIM...

本教程开始介绍的源代码将对每一帧执行PSNR测量,并且只对PSNR低于输入值的帧进行SSIM测量。为了可视化的目的,我们在OpenCV窗口中展示两幅图像,并将PSNR和MSSIM值打印到控制台。期望看到如下内容: video-input-psnr-ssim.cpp 将两…

JeeSite Vue3:前端开发控制实现基于身份角色的权限验证

随着技术的飞速发展,前端开发技术日新月异。在这个背景下,JeeSite Vue3 作为一个基于 Vue3、Vite、Ant-Design-Vue、TypeScript 和 Vue Vben Admin 的前端框架,引起了广泛关注。它凭借其先进的技术栈和丰富的功能模块,为初学者和团…

IP代理检测:判断IP质量优劣要注意什么?

做跨境电商的用户们往往对IP代理这个词都不会感到陌生,那么如何去评判IP的优劣势以及再选择IP时需要注意什么呢? 首先要知道的是IP代理检测是确保网络安全、提高网络访问效率以及满足特定需求的重要步骤。在判断IP代理质量优劣时,有几个关键…

使用阿里云试用Elasticsearch学习:1.1 基础入门——入门实践

阿里云试用一个月:https://help.aliyun.com/search/?kelastic&sceneall&page1 官网试用十五天:https://www.elastic.co/cn/cloud/cloud-trial-overview Elasticsearch中文文档:https://www.elastic.co/guide/cn/elasticsearch/guide…

剑指Offer题目笔记24(集合的组合、排序)

面试题79: 问题: ​ 输入一个不含重复数字的数据集合,找出它的所有子集。 解决方案: ​ 使用回溯法。子集就是从一个集合中选出若干元素。如果集合中包含n个元素,那么生成子集可以分为n步,每一步从集合中…

数据可视化:智慧农业发展的催化剂

数据可视化在智慧农业中发挥着不可替代的作用。随着科技的不断进步,农业领域也在不断探索创新,以提高生产效率、优化资源利用,从而实现可持续发展。而数据可视化技术的应用,则成为了实现智慧农业目标的重要途径。下面我就从可视化…

ABAP OOALV标题设置

ABAP OOALV标题设置 OOALV默认标题是SAP,需要我们自己创建GUI 标题 创建GUI 标题,写好要展示的描述 添加截图中的代码即可。 下面的ALV 报表标题修改的位置在以下代码区域。 这时候通过查询layout(wa_layout TYPE lvc_s_layo&#xff0…

mini2440移植lvgl(v8.2)

目录 概述 1 下载源码 1.1 登录LVGL git地址 1.2 LVGL linux平台上的库文件介绍 1.3 下载代码 1.3.1 下载lvgl 1.3.2 下载lv_drivers 1.3.3 下载lv_port_linux_frame_buffer 2 配置编译环境 2.1 创建工程目录 2.2 完善工程目录下的文件 2.2.1 构建工程文件 2.2.2 匹…

Oracle常用sql命令(新手)

1、备份单张表 创建复制表结构 create table employeesbak as select * from cims.employees 如果只复制表结构,只需要在结尾加上 where 10 插入数据 insert into employeesbak select * from cims.employees 删除一条数据 delete from…

水泥设备如何实现物联网远程监控?

水泥设备如何实现物联网远程监控? 在当今的工业4.0时代,水泥行业正在经历一场深度的技术革新,其中构建智慧工厂并采用物联网远程监控解决方案成为了提升生产效率、保障产品质量、实现节能减排的关键路径。该方案通过集成先进的信息技术、物联…

list使用与模拟实现

目录 list使用 reverse sort unique splice list模拟实现 类与成员函数声明 节点类型的定义 非const迭代器的实现 list成员函数 构造函数 尾插 头插 头删 尾删 任意位置插入 任意位置删除 清空数据 析构函数 拷贝构造函数 赋值重载函数 const迭代器的设计 …

【PostgreSQL】用pgAdmin轻松管理PostgreSQL

pgAdmin 是一个功能强大的开源Web界面工具,专为管理和维护PostgreSQL数据库而设计。它提供了一个直观的图形界面,使得用户能够轻松地执行复杂的数据库操作,如查询、更新、导入/导出数据以及管理数据库对象等。pgAdmin 支持几乎所有的PostgreS…

EasyExcel 模板导出excel、合并单元格及单元格样式设置。 Freemarker导出word 合并单元格

xls文件: 后端代码: InputStream filePath this.getClass().getClassLoader().getResourceAsStream(templateFile);// 根据模板文件生成目标文件ExcelWriter excelWriter EasyExcel.write(orgInfo.getFilename()).excelType(ExcelTypeEnum.XLS).withTe…

redis 数据库的安装及使用方法

目录 一 关系数据库与非关系型数据库 (一)关系型数据库 1,关系型数据库是什么 2,主流的关系型数据库有哪些 3,关系型数据库注意事项 (二)非关系型数据库 1,非关系型数据库是…

37.HarmonyOS鸿蒙系统 App(ArkUI) 创建第一个应用程序hello world

HarmonyOS App(ArkUI) 创建第一个应用程序helloworld 线性布局 1.鸿蒙应用程序开发app_hap开发环境搭建 3.DevEco Studio安装鸿蒙手机app本地模拟器 打开DevEco Studio,点击文件-》新建 双击打开index.ets 复制如下代码: import FaultLogger from ohos.faultL…

鸿蒙OS元服务开发说明:【WebGL网页图形库开发接口】

一、场景介绍 WebGL主要帮助开发者在前端开发中完成图形图像的相关处理,比如绘制彩色图形等。目前该功能仅支持使用兼容JS的类Web开发范式开发。 二、接口说明 表1 WebGL主要接口列表 鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术鸿蒙技术文档开发知识更…

elment UI el-date-picker 月份组件选定后提交后台页面显示正常,提交后台字段变成时区格式

需求&#xff1a;要实现一个日期的月份选择<el-date-picker :typeformData.dateType :value-formatdateFormat v-modelformData.leaveFactoryDateplaceholder选择月份></el-date-picker>错误示例&#xff1a;将日期显示类型(type)dateType或将日期绑定值的格式(val…

Java SpringBoot中优雅地判断一个对象是否为空

在Java中&#xff0c;可以使用以下方法优雅地判断一个对象是否为空&#xff1a; 使用Objects.isNull()方法判断对象是否为空&#xff1a; import java.util.Objects;if (Objects.isNull(obj)) {// obj为空的处理逻辑 }使用Optional类优雅地处理可能为空的对象&#xff1a; impo…

为何网易游戏会选择引入OceanBase数据库

本文作者&#xff1a;田维繁&#xff0c;网易游戏关系型数据库小组负责人 作为中国游戏开发领域的佼佼者&#xff0c;网易游戏始终站在网络游戏自主研发的前沿。其产品及周边产品线丰富多样&#xff0c;因此&#xff0c;为满足各种业务场景的需求&#xff0c;需要多种不同的数据…