游戏引擎中的物理应用
一、 角色控制器
Character Controller和普通的动态对象(Dynamic Actor )是不同的,主要的三个特点是:
- 它拥有可控制的刚体间的交互
- 假设它是有无穷的摩擦力(可以站停在位置上),没有弹性
- 加速和刹车几乎立即改变方向并传送
所以其实角色控制器其实是反物理的。
1.1 构建一个控制器
首先,这是一个具有以下两个特点的运动学对象(Kinematic Actor):
- 不受物理规则影响
- 对其他object可以产生力(交互)
形状上,一般使用胶囊体,且一般有内外两层,内层是实际的碰撞体,外层主要是防止对象与其他物体过近(从而避免高速运动下直接发生重叠的情况以及其他对象过近时相机视角出错的问题)
1.2 角色控制器的特点和小细节:
- Auto Slide 撞墙后自动沿着墙滑步
- Auto Stepping 爬楼梯要高度合适(跳太高反而会导致上顶很难设计)
- Max climb slopes 设置一个角度阈值,高于它时角色控制器应该无法冲上去
- Force Sliding Down 在比较陡峭(小于上述阈值,因为上述是基于原本就有冲量的基础)的斜坡应该要设置自动下滑
- Controller Volume Updata 简单讲就是游戏中角色随状态会改变它的体积(比如站蹲趴、变形等),所以会需要实时更新计算它的size,而在处理过程中,应该在更新之前进行重叠测试,防止因为物理系统处理的比较快等原因导致在实际上还不能改变到目标尺寸的时候就进行了更新
- Controller Push Objects 角色可以对其他动态物体施加力互动,往往以当时角色控制器的冲量进行计算
- Standing on Moving Platform 在这种情况下,一般在逻辑上把角色控制器和平台物体绑定在一起(除非要进行更高标准精细计算的情况),来防止平台移走角色下落的情况以及因为帧率问题导致的角色处在上下移动平台上时不断弹动的情况。
总的来说,角色控制器本身并不是多复杂的对象,但其拥有很多小细节和设计来模拟各种不同情况下的真实处理。
而作为引擎设计者,应在设计角色控制器时留有较多的处理空间给开发者进行不同的细节设计。
二、 布娃娃系统 Ragdoll
首先,为什么需要布娃娃系统?以一个简单的例子说明:当一个角色被刺杀后需要播放对应设计好的死亡动画,由于实际游戏中情况复杂,如果不引入布娃娃系统的话会导致比如在悬崖边死亡一半身体在外面的情况。而引入布娃娃系统就可以使其顺势掉落下去,合理很多。
具体来说,布娃娃系统就是利用了人物的joint和骨骼,一般设置的较粗略,最多也就十几个joint,然后设计彼此之间的限制和关系,从而形成合理的转变动作。
由于布娃娃系统的joint较少,并不覆盖所有原生骨骼joint,所以如何用布娃娃系统的joint去驱动整套骨骼呢?
将joint分为三类:
- Active joints — 这些joint上布娃娃系统和原本骨骼重叠,所以只需要直接用原骨骼系统去进行变化即可
- Leaf joints — 在布娃娃系统joint尽头未被覆盖的joint,使其保持动画设定的变化即可,跟着布娃娃系统尽头的joint变化延伸
- Intermediate joints — 在两个布娃娃系统joint之间的原生骨骼节点,一般使用插值均匀分到这些joint上进行限制性变化
另外,在实际游戏中,整个过程并不完全是由布娃娃系统进行,比如上述刺杀过程,一般是先进行对应的动画,当进行到一定情况时(比如快倒下时)交给物理系统进行判断布娃娃的处理。
而在更多情况下,动画和物理的区分并不像上述一样清晰,而是直接互相融合,比如抱着一个小女孩跑步的过程,一方面小女孩自身拥有一定的晃动动画,另一方面随着整体位置的移动,动画带来的角色物理信息会一起输入到物理系统去更新最终呈现出来的融合效果,使得避免动画单纯重复(只动画)和小女孩乱晃(只物理/布娃娃)。
三、 衣料模拟
衣料模拟方面,游戏开发发展过程中出现过三个经典方法,前两个为:
基于动画的衣料模拟 — Animation bone
把衣服当身体一样进行动画处理,在衣服上设置joint和骨骼,并进行相应的插值处理。优点在于便宜和可控(移动端),缺点在于不够真实、和环境没有交互以及设计上受限
基于刚体的衣料模拟 — Kinematic bone
像布娃娃系统一样设置一些骨骼joint,利用物理系统去进行计算处理。优点在于便宜和可交互,缺点在于质量不可控、动画师的工作量大、不鲁棒以及需要高质量物理系统参与
而我们的重点在于第三个衣料模拟方法:
3.1 基于mesh的衣料模拟
简单讲就是获得物体的mesh,并对每一个顶点进行计算处理。而由于物理系统计算的昂贵,所以一般不会像渲染时一样对每个顶点计算,而是相对稀疏。(少几倍到十倍)
具体做法上细节如下(以人物身上的衣料为例(披风)):
首先,对每一个顶点要设置最大的移动半径。一般来说,对离人物越近的顶点,最大移动半径越小(比如脖子处基本不动),一方面更符合物理实际,另一方面可以减少穿模概率
在游戏开发者角度来说,需要设置衣料的物理属性。以UE4为例,有如下属性:
结合上渲染系统,可以表现出不同材质和物理情况的衣料。
3.2 基于Mass-Spring系统
而在引擎开发者角度,衣料的实现是基于一个Mass-Spring系统。
我们只能把衣料处理成许多弹簧质点。针对每一个质点,它会收到两个力,一是弹簧弹力,与弹簧系数和位移大小有关;另一个是所谓damping force,是一个衰减力,与damping系数和速度有关。如下图:
这个衰减力主要是为了处理空气阻力(每一个质点代表的是实际的衣料上的一个小面,所以空气阻力并不小)和能量爆炸问题(随着迭代产生)
根据不同的需求和衣料特点,实际中如何设置弹簧质点各有不同,以最标准的每个顶点之间一个弹簧为例进行详细力的分析。取其中某个顶点为例进行受力分析:
其中,空气阻力是受速度影响的,简单计算就是速度乘以一个常量系数(虽然实际上应该是速度平方)。
获得加速度之后,可以直接利用Verlet公式进行计算下一帧的位置。
Verlet公式由上一课所提的半隐式欧拉法为基础进行转换得到,只需要利用上一帧位置和当前帧算出的加速度即可,成本低速度快。其另外一个值得注意的优点是避免了速度的计算,从而避免了速度突变导致的位移不稳定。
然而,现在最常用的是处理弹簧算法的方法是:Position Based Dynamics(PBD),其简单思想是用拉格朗日力学替代传统力学那一套,放弃“约束 - 力 - 速度 - 位置”的逻辑而把所有的力学关系描述成一套约束,并直接解出最后的位置,而不关心速度。
PBD在第六章会详细介绍。
衣料的另一个问题是自碰撞问题,同一件衣服之间、不同件衣服之间的碰撞十分复杂,解决方案有四个:
- 单纯把衣服变厚即可,这样即使有一定穿模也不影响
- 使用很多substep去精细的处理物料间的碰撞
- 设置一个最大速度阈值,防止衣料之间穿模的过深,还能弹回来
- 第三点的进阶,在衣料内部设置一个反向的力场,当有其他衣料穿进来时对其施加反方向的力将其弹出。
四、 破坏模拟
破坏系统的制作大概分为如下步骤:
-
设计架构 Chunk Hierarchy。将完整未被破坏的物体自然分割成不同大小的块并生成树状结构进行描述它们的关系。
-
建立不同块之间的联系,此时是指同一层的不同块之间的关系。设置它们联系的紧密程度。实时更新。
-
对每一个联系设置一个value值,表示当多大的力打到该部分时会打断其间的联系。其实也就是“硬度”。每次打击后更新其值(比如不断变小)。变成0时即断开。
-
计算从冲量产生的伤害值 D = I / H 。I是指撞击给的冲量,H是指刚体的材料硬度。
-
计算球体撞击的伤害值D。结果分段,在比较小的范围内物体收到相同的完全的伤害,在最大伤害范围外物体不受到伤害,在中间从内到外插值不断减小。
-
另外,当撞击发生时,有没有support graph也会影响结果
-
步骤1中所述自然分割怎么实现?— Voronoi Cell。简单讲就是在物体上随机撒一些种子,每个种子不断扩大直至撞到其他种子区域,当全部稳定下来后就形成不同的块。3维物体的切割也是类似。只是最后要用一个分割四面体的方法。
-
分割3维物体的一个难点是处理切割处的纹理问题,一般有两种方式:1、直接制作对应的三维纹理,切割时直接用(麻烦、贵)2、离线计算好这些纹理,一旦破碎则切换到对应的纹理,(要瞬时处理)。简而言之都很复杂。
-
另外,碎的方式也可以设计的不一样,均匀的、随机的、中心往外碎等等。
-
再另外,碰撞对应的声效、粒子效果等都会增加真实性。
五、 载具模拟
-
首先是形状,由一个刚体构成,还有一些弹簧等组件。
-
其次是动力(静摩擦力)组成,如下图:
由引擎扭矩经过一系列操作获得轮胎扭矩,再从而获得摩擦力F。 -
悬挂力(Suspension Force)。轮胎是悬挂在车上的(利用弹簧),所以有一个随着轮胎离车体距离形成的弹簧弹力。
-
轮胎力。分两个:一是向前的纵向力,由向前的拉力(如上述)和反向的拉力和转动阻力组成;二是横向力(用于转弯),是由滑动摩擦力和角度构成。最终方向由两个力的合力构成。
-
重心也很影响车的设计和体验。重心本身的计算就是两轮之间重量的中心点;在跳跃、转弯时重心靠前和靠后会发生不一样的接过,一般来说,重心靠后会让车更稳定、转弯时更容易转大弯。
-
Weight Transfer。在实际驾驶中,汽车的重心是会发生变化的,主要是由驱动力产生(加速时靠后,减速时前移等)。
-
Steering angles 驾驶角度。当前面两个轮胎转动一样角度时,靠外的轮胎会发生空转。所以实际驾驶中两个轮胎的转动角度是不一样的,具体是由轮胎到转动圆的圆心的连线(半径)的垂线(其实就是切线)决定。
-
Advanced Wheel Contact。比如在过减速带时,如果简单的进行raycast(当前轮胎被减速带穿模过了就往上抬,否则下降),会出现穿模。实际处理中要用spherecast,将轮胎整体以圆的形式去判断。
六、 高级:PBD与XPBD
6.1 PBD
拉格朗日力学:不同于牛顿力学中提到的物体的运动会受到限制(比如能量守恒),拉格朗日力学的思路正好相反,它由这些限制可以得出物体的运动方式(由能量守恒可以推出牛一定律)。
从而把很多力学问题化成了求解约束的问题。
具体来讲,以圆周运动为例:
其中X就是位置的向量。通过位置的约束和速度的约束可以反向得到运动的方式。
同理还有弹簧的约束:𝐶𝑠𝑡𝑟𝑒𝑡𝑐ℎ (𝐱1,𝐱2) = ||𝐱1 − 𝐱2|| − 𝑑
总结下来,PBD就是一个迭代的不断优化约束状态的过程(有点类似神经网络…),不需要计算速度等中间量,只需要让每一个量都梯度变化,去优化最终结果即可。一般停止迭代是要么当前约束误差小于阈值、要么迭代次数达到一定量。
PBD也需要在最后结束迭代时加上一个damping项来防止爆炸。
可以参考PBD (Position Based Dynamics)
6.2 XPBD
在PBD基础上加入stiffness参数来调节约束的软硬程度,具体可以参考XPBD (Extended PBD)
相关文章:
游戏引擎中的物理应用
一、 角色控制器 Character Controller和普通的动态对象(Dynamic Actor )是不同的,主要的三个特点是: 它拥有可控制的刚体间的交互假设它是有无穷的摩擦力(可以站停在位置上),没有弹性加速和刹车几乎立即…...
复现k8s黄金票据学习
1.什么是黄金票据 在 Kubernetes 中,"黄金票据"并不是一个常见的术语。可能你想了解的是服务账户(Service Account)。服务账户是 Kubernetes 中用于身份验证和授权的一种机制。它们允许 Pods 或其他工作负载在 Kubernetes 集群中与…...
08-JavaScript BOM定时器及JS动画
1. 设置定时器 1.1设置超时定时器 超时调用需要使用window对象的setTimeout()方法,该方法接受两个参数:调用函数或计算表达式和以毫秒为单位的时间(即在执行代码前需要等待多少毫秒)。 //setTimeout(callback, after) //callba…...
边缘计算盒子与云计算:谁更适合您的业务需求?
边缘计算盒子和云计算,这两个概念听起来可能有点复杂,但其实它们就是两种不同的数据处理方式。那谁更适合您的业务需求呢?咱们来详细说说。 边缘计算盒子,就像是个小型的数据处理中心,放在离你业务现场比较近的地方。它…...
浅聊什么是Redis?
需求:MySQL面临大量的查询,即读写操作,因此类比CPU,给数据加缓存,Redis诞生。应用程序从MySQL查询的数据,在Redis设置缓存(记录在内存中,无需IO操作),后再需要…...
java算法day43 | ● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零
1049. 最后一块石头的重量 II 核心思想: 尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。 是不是感觉和昨天讲解的416. 分割等和子集 (opens new window)非常像了。那么分成两堆石头,一堆石头的…...
练气第六天
问:ANR怎么分析? ANR问题,这其实是一个非常综合性的问题,因为anr会涉及CPU负载,内存空间大小,线程锁,GC回收,这里面每个点,都是非常考验我们基本功的。 分析ANR问题,需…...
认识 Redis 与 分布式
Redis 官网页面 Redis官网链接 Redis 的简介 Redis 是一个在内存中存储数据的中间件 一方面用于作为数据库,另一方面用于作为数据缓存,适用于分布式系统中 Redis 基于网络,进行进程间通信,把自己内存中的变量给别的进程…...
Linux初学(十二)AWK进阶
一、AWK 1.1 简介 AWK是Linux中重要的文本处理工具Linux三剑客只一处理的对象可以是一个具体的文件,也可以是一个命令的执行结果AWK按行读取文件,将每一行视为一条记录 案例一:获取系统中每个用户的uid 方法一:cat /etc/passwd |…...
文字识别 Optical Character Recognition,OCR CTC STN
文字识别 Optical Character Recognition,OCR 自然场景文本检测识别技术综述 将图片上的文字内容,智能识别成为可编辑的文本。 场景文字识别(Scene Text Recognition,STR) OCR(Optical Character Recognition, 光学字符识别)传统上指对输入扫描文档图像进行分析处理,识…...
四、MySQL读写分离之MyCAT
一、读写分离概述 1、什么是读写分离: 读写分离:就是将读写操作分发到不同的服务器,读操作分发到对应的服务器 (slave),写操作分发到对应的服务器(master) ① M-S (主从) 架构下&…...
通讯录项目实现
引言:通过顺序表的逻辑实现通讯录。这里就不讲关于顺序表的函数了。如果有不明白的可以看我写的顺序表的博客。 目录 顺序表与通讯录的比较 各源文件文件大榄 Contact.c中通讯录相关函数的定义 初始化和销毁通讯录 添加联系人: 删除联系人…...
xss相关知识点与绕过思路总结
前言 对xss的绕过进行了系统的学习与实践后,重新审视一下xss,对他的绕过进行一个总结。 (当然我也是个小白,这些也是我当时瞎鸡儿乱搞绕过了几个xss自己做的小总结) 可能有点丑陋,献丑了。 好博客推荐 …...
深入解析语言模型:原理、实战与评估
引言 随着人工智能的飞速发展,语言模型作为自然语言处理(NLP)的核心技术之一,日益受到业界的广泛关注。本文旨在深入探讨语言模型的原理、实战应用以及评估方法,帮助读者更好地理解和应用这一技术。 一、语言模型原理…...
Elasticsearch 的索引优化常规项
优化常规项 https://blog.csdn.net/bairo007/article/details/132019575 1、按实际情况适当调整主分片的数量 如果主分片数量太少,会导致每个分片中的数据量过大,而且无法利用集群中所有节点的计算资源。如果主分片数量太多,会导致索引过度…...
【JavaParser笔记01】JavaParser解析Java源代码中的类信息(javadoc注释、类名称)
这篇文章,主要介绍如何使用JavaParser解析Java源代码中的类信息(javadoc注释、类名称)。 目录 一、JavaParser依赖库 1.1、引入依赖 1.2、获取类注释信息...
Stable Diffusion扩散模型【详解】小白也能看懂!!
文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导,需要参考这篇文章: Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…...
关于rabbitmq的prefetch机制
消息预取机制(Prefetch Mechanism)是RabbitMQ中用于控制消息传递给消费者的一种机制。它定义了在一个信道上,消费者允许的最大未确认的消息数量。一旦未确认的消息数量达到了设置的预取值,RabbitMQ就会停止向该消费者发送更多消息…...
机器学习介绍
机器学习是人工智能(AI)的一个分支,它使计算机系统能够从数据中学习并改进它们的性能。机器学习的核心在于开发算法,这些算法可以从大量数据中识别模式和特征,并用这些信息来做出预测或决策,而无需进行明确…...
OpenCV4.9开发之Window开发环境搭建
1.打开OpenCV所在github地址 2.点击opencv仓库,进入仓库详情,点击右下方的OpenCV 4.9.0进入下载页面 3.点击opencv-4.9.0-windows.exe下载 开始下载中... 下载完成 下载完成后,双击运行解压,默认解压路径,修改为c:/...
DDD 中的实体和值对象有什么区别?
在DDD中,实体 Entity 和值对象 Value Object 是两个基本的概念,它们之间有一些重要的区别。 唯一性:实体是唯一的,每个实体都有一个唯一的标识符,即使它的属性在一段时间内发生了变化,它仍然是这个实体。与…...
算法-最值问题
#include<iostream> using namespace std; int main() {int a[7];//上午上课时间int b[7];//下午上课时间int c[7];//一天总上课时间for (int i 0; i < 7; i) {cin >> a[i] >> b[i];c[i] a[i] b[i];}int max c[0];//max记录最长时间int index -1;//索…...
Go 性能压测工具之wrk介绍与使用
在项目正式上线之前,我们通常需要通过压测来评估当前系统能够支撑的请求量、排查可能存在的隐藏bug;压力测试(压测)是确保系统在高负载情况下仍能稳定运行的重要步骤。通过模拟高并发场景,可以评估系统的性能瓶颈、可靠…...
数学思想论(有目录)
数学思想是数学发展过程中的重要指导原则,它涉及对数学概念、方法和理论的理解和认识,以及如何利用这些工具来解决实际问题。数学思想的形成和演进是随着数学的发展而逐渐深化的,它体现了人类对数学本质和应用的不断探索和思考。 一些主要的数学思想包括: 函数与方程思想…...
C++的并发世界(五)——线程状态切换
0.线程状态 初始化:该线程正在被创建; 就绪:该线程在列表中就绪,等待CPU调度; 运行:该线程正在运行; 阻塞:该线程被阻塞挂机,Blocked状态包括:pendÿ…...
C语言——指针
地址是由物理的电线上产生的,能够标识唯一一个内存单元。在C语言中,地址也叫做指针。 在32位机器中,有32根地址线。地址是由32个0/1组成的二进制序列,也就是用4个字节来存储地址。 在64位机器中,有64根地址线。地址是…...
手搓二分查找
第一种: 该种方法是若a[mid]目标数,则让r一直等于mid,让l往右移动,一直移动到rl,这时候跳出循环,在循环外判断 但是不能写成让lmid,让r往左移动,比如a[2]key,这时&#x…...
pycharm调试(步过(Step Over)、单步执行(Step Into)、步入(Step Into)、步出(Step Out))
pycharm调试 pycharm调试 pycharm调试为什么要学会调试?1. 步过 (Step Over)2. 单步执行 (Step Into)3. 步入(Step Into)4. 步出(Step Out) 为什么要学会调试? 调试可以帮助初学者更深入地理解编程基础&am…...
Linux是什么,该如何学习
🐇明明跟你说过:个人主页 🏅个人专栏:《Linux :从菜鸟到飞鸟的逆袭》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Linux的起源与发展 2、Linux在现代计算机领域…...
C++ | Leetcode C++题解之第7题整数反转
题目: 题解: class Solution { public:int reverse(int x) {int rev 0;while (x ! 0) {if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {return 0;}int digit x % 10;x / 10;rev rev * 10 digit;}return rev;} };...
宜宾做网站的公司/网络热词2022流行语及解释
在android提供了一种类型:Parcel。被用作封装数据的容器,封装后的数据可以通过Intent或IPC传递。 除了基本类型以外,只有实现了Parcelable接口的类才能被放入Parcel中。Parcelable实现要点:需要实现三个东西1)writeToParcel 方法。…...
天津品牌网站建设公司/app怎么推广运营
目录 【JeecgBoot-Vue3】零基础入门 - 首页 一、场景 二、树结构表CRUD Step 1:新增表 Step 2:填写 表名 > 表描述 Step 3:新增字段 > 数据库属性 Step 4:新增字段 > 页面属性 Step 5:保存ÿ…...
网站怎么做图片按按钮跳转/百度搜索引擎提交入口
晚上的时候PC问了一下这玩意,回忆一下极角排序 相关链接: How Many Triangles HDU - 5784(极角排序,双指针) 2019秦皇岛A - Angle Beats Gym - 102361A(极角排序,多少个直角三角形)…...
长春网站建设加王道下拉/推广关键词优化公司
https://www.cnblogs.com/kumata/p/13304292.html...
wordpress 获取插件数据/农产品网络营销方案
在零售业、IT业、金融业、保险业的众多公司中,优秀人才的储备和保留都作为公司人力资源发展的重要一环。连续两年入选"中国最受尊敬的企业"的沃尔玛中国公司,采用了挽留面谈、员工离职后的跟踪分析、流失率与部门主管责任挂钩的方式࿰…...
kratos主题wordpress/16888精品货源入口
本系列目的: 列出TypeScript与JavaScript的不同点, 缩小文档内容, 提高学习速度. 原文档地址: https://www.tslang.cn/index.html 全系列目录 1.基础类型 https://blog.csdn.net/c_kite/article/details/852320212.接口 https://blog.csdn.net/c_kite/article/details/852620…...