游戏物理

游戏物理总给人一种神秘的面纱,大多数玩家在游戏的过程中应该能体会到游戏的物理表现,比如dota里面的碰撞,前面有物体你就无法走动,对人释放技能将其击晕或击退,技能造成的地面效果,都是和物理有关的,就让本菜来揭开游戏物理的神秘,它到底是怎么实现的

首先必须要提到物理引擎和渲染引擎的框架

渲染引擎就是决定屏幕最终画面的效果,屏幕画面全是由像素组成的,这一屏的像素对应于一帧的内容,也就是后备缓存区的内容,游戏总是至少有两个缓存,当前显示的缓存和后备缓存,一个缓存显示当前内容,另一个缓存绘制下一帧的内容,然后交换,由于帧频很快超过30帧每秒就会给人画面连续的感觉,渲染引擎大致就是让游戏场景更漂亮,可以说画质好不好跟这个渲染引擎是直接相关的

本菜还没有进入shader编程的殿堂我就不多说渲染引擎了,游戏是由场景组成,场景是由物体组成,计算机每秒绘制几十次屏幕,只要物体每次被绘制在它应该存在的地方那么玩家就觉得是真实的,这很容易理解,渲染引擎可以把物体绘制到场景中的任何地方,只要它知道物体的位置和面向(也就是物体自身的朝向),那么物体的位置和面向怎么来得到?

针对于静态的场景物体,每次绘制的时候物体的位置和面向是不变的,比如游戏里面的建筑,山脉,树木,但是对于运动的物体,渲染引擎怎么得到它的位置和面向?如果只是每帧简单的改变一定的角度和位置,尽管看起来物体是运动的,但是会发现完全不符合实际,比如物体自由落体是匀加速运动的,物体碰撞是要彼此弹开的,地面有摩擦,物体在地面运动是最终要停止的,这些只靠简单的每帧渲染改变位置和面向是完全不行的,于是游戏的大杀器,物理引擎诞生了

物理引擎当然是让物体具有真实的物理表现,主要就是模拟现实世界的物理行为,让游戏表现更为正确真实,物理引擎没有渲染引擎那么好玩,它就是一个黑盒子,它为渲染引擎服务,计算物体的位置和面向,提交数据给渲染引擎,最终将物体绘制在场景的正确位置上

物理引擎如何模拟物理效果?

这里就基于刚体来说吧,毕竟刚体是场景物体的主要形式,也是物理引擎里最重要的研究对象。刚体是由自身属性和状态组成

刚体属性:质量,体积,惯性张量,表面摩擦系数,弹性系数等等一切不受其他物体影响的特征

刚体状态:线速度,角速度,线加速度,角加速度,位置,面向,外力,转矩,冲量 等等一切能够受其他物体和环境影响的特征

渲染引擎将刚体模型和场景物体绑定,初始化刚体属性和状态,在每一帧绘制之前,物理引擎计算物体状态数据提交回给渲染引擎,然后渲染引擎绘制物体,然后下一帧绘制之前,物理系统计算物体状态数据提交给渲染引擎,然后绘制......依次循环。大致就是这样了,物理引擎只做计算,提交数据,刚体的属性和初始状态由渲染引擎提供,后面渲染引擎就不管这些事了,只做渲染

物理引擎怎么计算?

前一帧和后一帧之间的绘制是有时间差的,在渲染当前帧的内容时,物理引擎就在计算下一帧物体的状态,在这个时间差里,大多数物理引擎都将速度,加速度认为是固定的量,这也正是物理引擎总是不能做到绝对精确的根本原因,因为现实物理量是连续变化的,计算机只能处理固定数值量,必然导致误差,所以大多数物理引擎都会选择两种办法来弥补,一是降低误差,二是补偿误差

大致计算是这样,首先根据所受的合外力算出线性加速度,根据受到的转矩算出角加速度,根据角加速度和线加速度算角速度和线速度,根据角速度和线速度算角位移和线性位移,然后更新状态数据,主要就是线速度,角速度,线加速度,位置,面向

这全是数值积分的知识,最终是要得到刚体的位置和面向提交给渲染引擎,只是考虑的问题异常复杂,所以很多时候只能简化和假设

物理引擎最核心的内容就是刚体碰撞检测和处理,想要游戏表现真实,比如角色不穿墙而过,就必须处理角色和墙之间的碰撞,凡是物体互相接触都属于这个范畴,涉及动态物体和静态物体,动态物体和动态物体,静态物体和静态物体之间的碰撞,主要是这三种形式

就基于最复杂的动态物体和动态物体来说吧

动态物体和动态物体,当然在物理引擎里面应该称为刚体和刚体,首先刚体就代表场景物体,它是简化的,场景物体异常复杂,比如角色,它不规则,可能是由上万个三角面构成的,这么复杂的物体,物理引擎要计算两个角色的碰撞点,必须处理每一个三角面那是非常低效的,所以第一步简化物体模型,一般的物理引擎采用包围球或者包围合来替代物体,这里就认为它是以包围盒的形式来处理吧

用包围合替代角色就大大简化了模型了,盒子只有六个面,物理引擎处理起来就非常快速了,但另一个问题又来了,场景非常复杂,场景中的物体异常多,尽管每一个物体都用包围盒替代,但是数量依然巨大,物理引擎处理起来依然吃不消,怎么办?

这也是有办法的,试想,一个物体在场景的天上,一个物体在地上,这种情况我们根本不用处理他们之间的碰撞问题,他们不存在碰撞问题,好在游戏中绝大部分情况都是如此,引擎真正要处理的碰撞只是很小的一个子集,所以必须先确定这个子集,这一步称为粗略碰撞检测

粗略碰撞检测可以迅速的确定潜在碰撞集合,这里大多数物理引擎采用层次包围体或者空间划分技术来处理,相关内容有很多学术论文进行过研究,本菜只是揭开面纱,不深究,所以只引入概念。

粗略碰撞得到的是潜在碰撞结合,这是因为物体是由简化的包围盒或者包围球简化替代的,所以包围合相交了不代表物体也相交了,这个很容易理解,但是粗略碰撞检测器是宁错过不放过,将所有相交集合全部记录下来,然后提交给精确碰撞系统

精确碰撞系统一方面剔除没有真正相交的物体,一方面确定碰撞点,碰撞法线和相交深度,这是最重要的碰撞数据,然后将这些数据提交个碰撞处理系统。这里我只解释一下什么是相交深度。

这里只是谈的刚体,对于刚体他们之间是不能相互贯穿的,这是真实的物理现象,也可说是常识,但是计算机如何做到?在每一帧绘制之前,两个物体的位置将被确定,这很可能就出现两个物体彼此贯穿的情况,如果这种画面被显示出来绝对是被吐槽的,所以碰撞系统必须处理刚体相交的情况,于是将刚体彼此相交的最大深度称为相交深度

由精确碰撞计算出的数据将提交给碰撞处理系统,这也是物理引擎中异常复杂和核心的功能,它主要完成更新速度和相交处理,决定刚体最终速度以及消除相交深度,让物体表现真实

本菜简单描述一下如何计算速度

大致是这样,由闭合速度和分离速度算出冲量,由冲量算出线速度和角速度,由角速度和线速度算出位置和面向,很简洁的描述,内部是波涛汹涌,异常复杂,涉及刚体转动和相对速度,以及坐标系统的变换,本菜只提概念不作深究

基本上经过碰撞处理系统的洗礼,物体已经表现得比较真实了,然后将位置,面向数据提交给渲染系统,绘制出来的效果就足以欺骗玩家的眼睛了,对,就是做到欺骗人的眼睛就可以了。

据我所知国内游戏引擎开发基本上不写物理引擎的,成本太高了,毕竟有优秀的商业级库可以使用,本菜也只是想自己的游戏能添加自己的物理库才有研究的兴趣




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值