当前位置: 首页 > news >正文

游戏引擎中的物理系统

一、物理对象与形状

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)中出现两方不一样的问题。

相关文章:

游戏引擎中的物理系统

一、物理对象与形状 1.1 对象 Actor 一般来说,游戏中的对象(Actor)分为以下四类: 静态对象 Static Actor动态对象 Dynamic Actor ---- 可能受到力/扭矩/冲量的影响检测器 TriggerKinematic Actor 运动学对象 ---- 忽略物理法则…...

【C++ STL有序关联容器】map 映射

文章目录 【 1. 基本原理 】【 2. map 的创建 】2.1 调用默认构造函数,创建一个空的 map2.2 map 被构造的同时初始化2.3 通过一个 queue 初始化另一个 queue2.4 取已建 map 中指定区域内的键值对,初始化新的 map2.5 指定排序规则 【 2. map 元素的操作 】…...

【ZZULIOJ】1041: 数列求和2(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 输入一个整数n,输出数列1-1/31/5-……前n项的和。 输入 输入只有一个整数n。 输出 结果保留2为小数,单独占一行。 样例输入 Copy 3 样例输出 Copy 0.87 code import java.util…...

C++【适配器模式】

简单介绍 适配器模式是一种结构型设计模式 | 它能使接口不兼容的对象能够相互合作。(是适配各种不同接口的一个中间件) 基础理解 举个例子:当你引用了一个第三方数据分析库,但这个库的接口只能兼容JSON 格式的数据。但你需要它…...

go | 上传文件分析 | http协议分析 | 使用openssl 实现 https 协议 server.key、server.pem

是这样的&#xff0c;现在分析抓包数据 test.go package mainimport ("fmt""log""github.com/gin-gonic/gin" )func main() {r : gin.Default()// Upload single filer.MaxMultipartMemory 8 << 20r.POST("/upload", func(c *g…...

Chatgpt掘金之旅—有爱AI商业实战篇|专业博客|(六)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业博客领域有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着AI技…...

单例模式 JAVA

单例模式 什么是单例模式&#xff1f; 1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。 应用&#xff1a;数据库的连接类&#xff0c;这样就可以确保只创建一次。节省资源。 单例模式代码&#xff1a;涉及懒加载…...

C++从入门到精通——初步认识面向对象及类的引入

初步认识面向对象及类的引入 前言一、面向过程和面向对象初步认识C语言C 二、类的引入C的类名代表什么示例 C与C语言的struct的比较成员函数访问权限继承默认构造函数默认成员初始化结构体大小 总结 前言 面向过程注重任务的流程和控制&#xff0c;适合简单任务和流程固定的场…...

GitHub入门与实践

ISBN: 978-7-115-39409-5 作者&#xff1a;【日】大塚弘记 译者&#xff1a;支鹏浩、刘斌 页数&#xff1a;255页 阅读时间&#xff1a;2023-08-05 推荐指数&#xff1a;★★★★★ 好久之前读完的了&#xff0c;一直没有写笔记。 这本入门Git的书籍还是非常推荐的&#xff0c;…...

centos 安装 stable-diffusion 详细流程

一、安装git 新版 先安装git 工具来更新git源码 &#xff0c; 载下源码后卸载git 版本(centos 默认1.8版本&#xff0c;说是安装会引起失败) 安装git 命令&#xff0c;可使用 git --version查看版本 sudo yum install git -y 卸载git命令 sudo yum remove git 正式源码安装…...

CSS编写登录框样式

/* 重置浏览器默认样式 */ * { margin: 0; padding: 0; box-sizing: border-box; } /* 设置登录框的基本样式 */ .login-box { width: 100%; max-width: 400px; margin: 50px auto; background-color: #f4f4f4; padding: 20px; box-shad…...

Python|OpenCV-获取鼠标点击位置的坐标,并绘制图像(13)

前言 本文是该专栏的第14篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 本文主要来详细说明,基于OpenCV来获取鼠标点击位置的坐标,并按坐标的位置进行自动绘制图像。具体怎么实现,笔者在正文中将结合实际代码案例进行详细说明。 具体细节部分以及完整代码的实…...

设计模式(14):命令模式

介绍 将一个请求封装为一个对象&#xff0c;从而使我们可用不同的请求对象客户进行参数化&#xff1b;对请求排队或者记录请求日志&#xff0c;以及支持可撤销的操作。也称之为&#xff1a;动作Action模式&#xff0c;事务transaction模式。 命令模式角色 抽象命令类(Comman…...

关于阿里云云数据库自动扩缩容和自动SQL优化的20道面试题

1. 请解释阿里云云数据库自动扩缩容的概念及其工作原理。 阿里云云数据库自动扩缩容是一种基于数据库实例的实时性能数据&#xff0c;能够发现流量异常并提供合理的数据库规格建议和磁盘容量建议的功能。其工作原理如下&#xff1a; 性能监控&#xff1a;系统会实时监控数据库…...

mkcert生成ssl证书+nginx部署局域网内的https服务访问问题

文章目录 mkcert生成ssl证书nginx部署局域网内的https服务访问问题1、下载mkcert查看自己的电脑是arm还是amd架构 2、安装mkcert3、测试mkcert是否安装成功4、查看CA证书存放位置5、打开windows的证书控制台6、生成自签证书,可供局域网内使用其他主机访问以下是nginx部署https服…...

PTA C 1050 螺旋矩阵(思路与优化)

本题要求将给定的 N 个正整数按非递增的顺序&#xff0c;填入“螺旋矩阵”。所谓“螺旋矩阵”&#xff0c;是指从左上角第 1 个格子开始&#xff0c;按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列&#xff0c;满足条件&#xff1a;mn 等于 N&#xff1b;m≥n&#xff1b;且…...

神经网络分类和回归任务实战

学习方法&#xff1a;torch 边用边学&#xff0c;边查边学 真正用查的过程才是学习的过程 直接上案例&#xff0c;先来跑&#xff0c;遇到什么解决什么 数据集Minist 数据集 做简单的任务 Minist 分类任务 总体代码&#xff08;可以跑通&#xff09; from pathlib import …...

【数据结构】考研真题攻克与重点知识点剖析 - 第 4 篇:串

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…...

深入浅出 -- 系统架构之分布式多形态的存储型集群

一、多形态的存储型集群 在上阶段&#xff0c;我们简单聊了下集群的基本知识&#xff0c;以及快速过了一下逻辑处理型集群的内容&#xff0c;下面重点来看看存储型集群&#xff0c;毕竟这块才是重头戏&#xff0c;集群的形态在其中有着多种多样的变化。 逻辑处理型的应用&…...

STL —— list

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C专栏 本篇文章主要讲解 list模拟实现的相关内容 &#xff11;. list简介 列表&#xff08;list&#xff09;是C标准模板库&#xff08;STL&#xff09;中的一个容器&#xff0c;它是一个双向链表数据结构&#xff0c…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积

1.题目介绍 给定一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...