游戏引擎中的物理应用

一、 角色控制器

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在第六章会详细介绍。

衣料的另一个问题是自碰撞问题,同一件衣服之间、不同件衣服之间的碰撞十分复杂,解决方案有四个:

  1. 单纯把衣服变厚即可,这样即使有一定穿模也不影响
  2. 使用很多substep去精细的处理物料间的碰撞
  3. 设置一个最大速度阈值,防止衣料之间穿模的过深,还能弹回来
  4. 第三点的进阶,在衣料内部设置一个反向的力场,当有其他衣料穿进来时对其施加反方向的力将其弹出。

四、 破坏模拟

破坏系统的制作大概分为如下步骤:

  1. 设计架构 Chunk Hierarchy。将完整未被破坏的物体自然分割成不同大小的块并生成树状结构进行描述它们的关系。在这里插入图片描述

  2. 建立不同块之间的联系,此时是指同一层的不同块之间的关系。设置它们联系的紧密程度。实时更新。在这里插入图片描述

  3. 对每一个联系设置一个value值,表示当多大的力打到该部分时会打断其间的联系。其实也就是“硬度”。每次打击后更新其值(比如不断变小)。变成0时即断开。在这里插入图片描述

  4. 计算从冲量产生的伤害值 D = I / H 。I是指撞击给的冲量,H是指刚体的材料硬度。在这里插入图片描述

  5. 计算球体撞击的伤害值D。结果分段,在比较小的范围内物体收到相同的完全的伤害,在最大伤害范围外物体不受到伤害,在中间从内到外插值不断减小。在这里插入图片描述

  6. 另外,当撞击发生时,有没有support graph也会影响结果在这里插入图片描述

  7. 步骤1中所述自然分割怎么实现?— Voronoi Cell。简单讲就是在物体上随机撒一些种子,每个种子不断扩大直至撞到其他种子区域,当全部稳定下来后就形成不同的块。3维物体的切割也是类似。只是最后要用一个分割四面体的方法。

  8. 分割3维物体的一个难点是处理切割处的纹理问题,一般有两种方式:1、直接制作对应的三维纹理,切割时直接用(麻烦、贵)2、离线计算好这些纹理,一旦破碎则切换到对应的纹理,(要瞬时处理)。简而言之都很复杂。

  9. 另外,碎的方式也可以设计的不一样,均匀的、随机的、中心往外碎等等。

  10. 再另外,碰撞对应的声效、粒子效果等都会增加真实性。

五、 载具模拟

  • 首先是形状,由一个刚体构成,还有一些弹簧等组件。

  • 其次是动力(静摩擦力)组成,如下图:在这里插入图片描述
    由引擎扭矩经过一系列操作获得轮胎扭矩,再从而获得摩擦力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)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Django学习笔记(三)】BootStrap介绍

BootStrap介绍 前言正文1、BootStrap 快速了解2、初识BootStrap2.1 下载地址2.2 创建目录2.3 引入BootStrap2.4 使用BootStrap 3、BootStrap 组件&样式3.1 导航条3.2 栅格系统3.3 container3.3.1 container3.3.2 container-fluid 3.4 面板3.5 媒体对象3.6 分页3.7 图标3.7.…

外卖配送时间预测项目

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 ([www.aideeplearning.cn]) 项目背景 外卖服务的兴起: 随着互联网技术和移动应用的发展,外卖成为一种日益普及的餐饮服务方式。顾客通过餐厅、杂货店的网站或移…

Qt中继承QCheckBox的类结合QTableWidget实现多选并且每个多选的id都不一样

1.相关描述 继承QCheckBox的类MyCheckBox&#xff0c;利用QTableWidget的setCellWidget方式添加MyCheckBox类的对象 2.相关页面 3.相关代码 mycheckbox.h #ifndef MYCHECKBOX_H #define MYCHECKBOX_H#include <QCheckBox> #include <QObject>class MyCheckBox : pu…

计算机网络:数据链路层 - 封装成帧 透明传输 差错检测

计算机网络&#xff1a;数据链路层 - 封装成帧 & 透明传输 & 差错检测 数据链路层概述封装成帧透明传输差错检测 数据链路层概述 从数据链路层来看&#xff0c;主机 H1 到 H2 的通信可以看成是在四段不同的链路上的通信组成的&#xff0c;所谓链路就是从一个节点到相邻…

从0到1构建uniapp应用-store状态管理

背景 在 UniApp的开发中&#xff0c;状态管理的目标是确保应用数据的一致性&#xff0c;提升用户体验&#xff0c;并简化开发者的工作流程。通过合理的状态管理&#xff0c;可以有效地处理用户交互、数据同步和界面更新等问题。 此文主要用store来管理用户的登陆信息。 重要…

数据结构——图的应用(最小生成树,最短路径,拓扑排序,关键路径)

目录 1.最小生成树 1.概念回顾——生成树 2.最小生成树概念 2.构造最小生成树 1.MST性质 2.Prim算法 3.Kruskal 算法 4.两种算法比较 3.最短路径 1.两点间最短路径 2.某源点到其它各点最短路径 3.单源最短路径——用Dijkstra算法 4.所有顶点间的最短路径…

QML嵌套页面的实现学习记录

StackView是一个QML组件&#xff0c;用于管理和显示多个页面。它提供了向前和向后导航的功能&#xff0c;可以在堆栈中推入新页面&#xff0c;并在不需要时将页面弹出。 ApplicationWindow {id:rootvisible: truewidth: 340height: 480title: qsTr("Stack")// 抽屉:…

【GlobalMapper精品教程】073:像素到点(Pixels-to-Points)从无人机图像轻松生成点云

文章目录 一、工具介绍二、生成点云三、生成正射四、生成3D模型五、注意事项一、工具介绍 Global Mapper v19引入的新的像素到点工具使用摄影测量原理,从重叠图像生成高密度点云、正射影像及三维模型。它使LiDAR模块成为已经功能很强大的的必备Global Mapper扩展功能。 打开…

Linux的中间件

我们先补充点关于awk的内容 awk的用法其实很广。 $0 表示整条记录 变量&#xff1a; NF 一行中有多少个字段&#xff08;表示字段数&#xff09; NR &#xff1a; 代表当前记录的序号&#xff0c;从1开始计数。每读取一条记录&#xff0c;NR的值就会自动增加1。&#xff08;…

编程生活day6--回文子串、蛇形填充数组、笨小猴、单词排序

回文子串 题目描述 给定一个字符串&#xff0c;输出所有长度至少为2的回文子串。 回文子串即从左往右输出和从右往左输出结果是一样的字符串&#xff0c;比如&#xff1a;abba&#xff0c;cccdeedccc都是回文字符串。 输入 一个字符串&#xff0c;由字母或数字组成。长度5…

【设计原则】CQRS

文章目录 概述组成与特点优缺点何时使用 CQRS 模式推荐阅读 概述 CQRS&#xff08;Command Query Responsibility Segregation&#xff09;是一种软件设计模式&#xff0c;其核心设计理念是将一个对象的数据访问&#xff08;查询&#xff09;和数据操作&#xff08;命令&#…

显示器and拓展坞PD底层协商

简介&#xff1a; PD显示器或者PD拓展坞方案中&#xff0c;连接显示设备的Type-C端口主要运行在DRP模式&#xff0c;在此模式下可以兼容Source&#xff08;显卡&#xff09;、Sink&#xff08;信号器&#xff09;、DRP&#xff08;手机、电脑&#xff09;模式的显示设备。 Sou…

探索设计模式的魅力:揭秘B/S模式在AI大模型时代的蜕变与进化

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL应用》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自热榜文章&#xff1a;探索设计模式的魅力&#xff1a;揭秘B/S…

ArcGIS Pro导出布局时去除在线地图水印

目录 一、背景 二、解决方法 一、背景 在ArcGIS Pro中经常会用到软件自带的在线地图&#xff0c;但是在导出布局时&#xff0c;图片右下方会自带地图的水印 二、解决方法 解决方法&#xff1a;添加动态文本--服务图层制作者名单&#xff0c;然后在布局中选定位置添加 在状…

【星计划★C语言】c语言初相识:探索编程之路

&#x1f308;个人主页&#xff1a;聆风吟_ &#x1f525;系列专栏&#xff1a;星计划★C语言、Linux实践室 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️第一个c语言程序二. ⛳️数据类型2.1 &#x1f514;数据单位2.2 &…

【ARM 嵌入式 C 常用数据结构系列 25 -- container_of 宏 使用介绍】

文章目录 container_of 宏container_of 宏的定义container_of 使用示例应用场景总结 container_of 宏 在Linux内核编程中&#xff0c;container_of宏是一个非常有用的工具&#xff0c;它允许开发者从指向结构体中某个成员的指针反向获得包含它的完整结构体的指针。这在实现基于…

Vol.34 Good Men Project:一个博客网站,每月90万访问量,通过付费订阅和广告变现

今天给大家分享的案例网站是&#xff1a;Good Men Project&#xff0c;这是一个专门针对男性成长的博客网站&#xff0c;内容包括人际关系、家庭、职业发展等话题。 它的网址是&#xff1a;The Good Men Project - The Conversation No One Else Is Having 流量情况 我们先看…

Linux :进程的程序替换

目录 一、什么是程序替换 1.1程序替换的原理 1.2更改为多进程版本 二、各种exe接口 2.2execlp ​编辑 2.2execv 2.3execle、execve、execvpe 一、什么是程序替换 1.1程序替换的原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往…

LongAdder 和 Striped64 基础学习

cs&#xff0c;表示 Cell 数组的引用&#xff1b;b&#xff0c;表示获取的 base 值&#xff0c;类似于 AtomicLong 中全局变量的 value 值&#xff0c;在没有竞争的情况下数据直接累加到 base 上&#xff0c;或者扩容时&#xff0c;也需要将数据写入到 base 上&#xff1b;v&am…

32-2 APP渗透 - 移动APP架构

前言 app渗透和web渗透最大的区别就是抓包不一样 一、客户端: 反编译: 静态分析的基础手段,将可执行文件转换回高级编程语言源代码的过程。可用于了解应用的内部实现细节,进行漏洞挖掘和算法分析等。调试: 排查软件错误的一种手段,用于分析应用内部原理和行为。篡改/重打…