游戏引擎开发
2024-12-24 11:27:48 0 举报
AI智能生成
《游戏引擎开放》思维导图
作者其他创作
大纲/内容
Chapter1 导论
1.1 游戏开发团队
工程师
职责
运行时
工具
范围
通才
专才
等级
TD
CTO
艺术家
概念艺术家
3D建模师
纹理艺术家
灯光师
动画师
动捕
音效设计师
配音演员
作曲家
游戏设计师
故事主线,高层次目标
关卡
游戏制作人
管理嫉妒,开发,设计
其他
行政
市场
IT
1.2 游戏
软实时互动
1.3 游戏引擎
1.4 游戏类型
平台
FPS
竞速
格斗
RTS
MMO
沙盒
RPG
解谜
棋牌
1.5 引擎概览
Quake
id Software,开源
UE
Epic,UE4开源
Source
Valve
Frostbite
Dice
CryEngine
Crytek
PhyreEngine
Sony
XNA
Microsoft
Unity
OGRE
开源,可供学习
1.6 运行时引擎架构
上层依赖下层,反之不然
1.7 工具及资产管道
Chapter2 专业工具
2.1 版本控制
SVN,Git,Perforce
2.2 VS
2.3 剖析器
统计式
VTune
测控式
Rational Quantify
2.4 内存泄漏
Purify
Chapter3 软工基础
3.1 C++基础
面向对象,类,封装,继承,多态,组合,GoF,编码标准(接口,命名),c++11
3.2 数据,代码,内存
ICS基础
虚函数表
3.3 错误处理
开发者错误
中断执行,促使修复
足够健壮,依然工作
程序员错误
错误码
定义错误枚举值
抛出异常
额外开销,难定位,不推荐
断言
程序员使用,不要跳过
3.4 流水线,缓存,优化
推荐阅读Three Optimization Tips for C++
如今访存比计算更贵,更容易成为瓶颈
指令缓存与数据缓存结构(参考ICS基础)
写入策略
缓存一致
提高命中
数据编排至连续内存块
避免在最内层循环调用函数
内存布局
子主题
Chapter4 三维数学
推荐阅读Eric Lengyel
矢量,矩阵
四元数
旋转矩阵快,例如,计算逆矩阵虚部取反即可
四元数与选择矩阵的关系
为了保持插值旋转速度恒定,可酌情考虑SLERP
SIMD运算
SSE内部函数,需要#include <xmmintrin.h>,__m128必须8字节对齐,相比内联汇编,优化空间更大
随机数生成
LCG
X0为初始种子
MT19937
Xorshift
Chapter5 底层系统
5.1 子系统的启动与终止
c++原生,析构顺序不可知
利用静态函数,不可预计构造,不可控制析构,开销大
简单方案,放弃构造析构,手动控制开关,还可以设置优先级队列和依赖图
案例学习:OGRE,神秘海域
5.2 内存管理
优化动态内存分配
malloc和new慢,管理和上下文切换开销大
维持最低限度的堆分配,不在紧凑循环使用
制定自定义的内存分配器
推荐阅读Christian Gyrling
堆栈分配器
预分配大块内存,记录栈顶指针
释放时必须按照分配的相反次序
双端堆栈分配器
池分配器
预分配N个对象片段,每个片断有指向下个对象的指针
若元素尺寸小于指针,可直接用元素索引替代指针
https://blog.csdn.net/qq_29523119/article/details/102493565
对齐分配器
单帧分配器
每帧定时清空的堆栈分配器
双缓存分配器
双分配器交替使用,允许第i帧分配块用于第i+1帧
内存碎片问题
虚拟地址可解决(例如PC,但PS等进行虚拟映射开销太大)
堆栈(固定次序)和池分配器(对象大小恒定)不会出现该问题
洞后移可进行碎片整理,但会影响已分配指针,所以要进行指针重定位
智能指针全局列表,整理时遍历列表进行重定位
句柄实现为索引,整理时扫描句柄表
分摊碎片整理成本,每帧整理一小部分碎片
5.3 容器
迭代器
递增
后置递增相比前递递增,不会产生CPU数据依赖(p++比++p更好)
实现
自定义
STL
特点
丰富,健壮,c++自带
晦涩难懂,占用内存多
经验
占少量内存才使用(例如,顶点数据不推荐)
多平台推荐使用STLport
须谨慎使用,避免性能瓶颈
Boost
特点
补充STL
复杂功能(智能指针)
文档健全
Loki
模板元编程
推荐阅读《Modern C++ Design》
5.4 字符串
对性能影响大
字符串类
谨慎使用,考虑开销
是否copy-on-write
是否具有移动构造
散列标识符
散列过程昂贵,因此要把标识符也存起来,减少不必要的计算
本地化
推荐阅读参考文献【29】
编码模式
Unicode
char与wchar_t
存储使用csv或数据库(Oracle)均可
不要向玩家显示原始字符串,必须通过查找本地化数据库获取
5.5 引擎配置
配置模式
文本文件INI
由键值对构成
压缩的二进制文件
注册表和环境变量
案例分析:顽皮狗引擎,可配置选项为全局变量或单例成员,菜单获取extern变量的地址
Chapter6 资源系统
文件命名
Unix为“/”,windows为“\”
路径api
windows中的shlwapi.dll
IO操作
C中提供带缓存和无缓存的IO函数
建议包装自定义的IO函数
解决平台不一致,简化api,提供延申功能
同步IO
堵塞,必须读完才能继续程序,例如C标准库
异步IO
串流,载入数据与程序同时运行,具有不同优先权,例如CLR(System.IO.BeginRead())
资源管理
版本管理
使用版本管理系统,如Perforce,Alienbrain
符号链接访问远程数据库
元数据
手动记忆,嵌入资产或使用关系型数据库
数据库
UnrealEd负责一切事物,可寻找任何资源;资源存于大包,协作不方便
Builder粒度小,文件格式原生
工具链
处理资源格式
资源标识符
路径或哈希
资源注册表
key:标识符 value:内存对应指针
载入资源慢:运行中完全禁止,运行前加载好;异步加载,串流
资源生命期
不一而足,例如LSR贯穿游戏,有些仅限于某关卡
定期卸载引用计数为0的资源
内存管理
基于堆
PC上表现尚可(虚拟内存)
基于堆栈
也可使用双端堆栈,一边载入LSR,另一边载入关卡资源
基于池
将所有资源以组块布局
交叉引用
使用GUID
存储至二进制格式
加上指针偏移即可找到对应资源,转化为指针
二进制转回对象:PODS(空构造)对象和非PODS对象(二进制文件追加类名,调用对应构造)结合
初始化
载入临时内存(需要初始化进行处理,然后移动到最终内存)或最终内存
Chapter7 游戏循环
渲染循环
从早期二维重绘(类似html)到三维渲染循环
游戏循环
服务频率不同,例如,动画30-60hz,动力学120hz等
架构风格
视窗消息泵
主循环中先处理os的消息,再进行一次游戏循环
副作用,当玩家操作视窗时,游戏中断
回调驱动
使用监听器实现
基于事件
搭建消息系统
抽象时间
真实时间
基于cpu高分辨率计时器
游戏时间
实现特效(寅虎演出,对战结算慢动作),方便debug
局部时间
实现快慢,反转本质上是全局时间的映射
时间调控
基于其他单位定义速率(例如经过像素),受cpu影响大
基于真实时间,只需读取cpu计时器两次,即可得出dt
基于移动平均估计下一帧dt
基于固定帧率,快等慢调整
若dt大于一个阈值,判断从断点恢复,将其调整回默认值
时钟类
P376
多处理器架构
Xbox 360
PS3
PS4
分叉与汇合
分而治之,类似MapReduce
多线程控制
将相对独立的子系统运行于独立线程,库有Win32API,Unix pthread等
网络多人游戏循环
主从模型
p2p模型
案例分析《雷神之锤》源码
Chapter8 人体学接口设备
HID设备
接口技术
轮询,内核中断,蓝牙协议
输入类型
按钮,模拟式轴,相对性轴(鼠标),加速计等
信号噪声
死区,低通滤波
手势和序列检测
P415 历史缓冲区保存成分,对于后续的成分,检查是否在允许时间内
Chapter9 调试及开发工具
控制台输出
vs控制台,TTY等
调试绘画
线框球显示爆炸范围,圆形显示某半径等
注意,不是直接画而是加入绘制列表
内置菜单
减少编译成本,方便直接调试
内置主控台
例如minecraft
性能分析器
层阶分析,例如大部分语言,函数套函数
内存统计和泄露检测
难点,有些第三方库无法预测,显存等也无法直接管理
Chapter10 渲染引擎
光栅化
三角形图元
LOD
渐进网格
存储
索引表
顶点缓冲与索引缓冲
三角形带
光色概论
吸收,反射,折射,衍射(不考虑)
颜色空间与颜色模型
顶点属性
位置矢量,法矢量,切矢量,漫反射,镜面,蒙皮
属性插值
纹理贴图
纹素密度(像素/纹素)与多级渐远纹理
纹理采样
最近邻,双线性,三线性,各向异性
光照基础
光照模型
局部光照模型
只考虑直接光
Phong氏模型
环境+漫反射+镜面反射 P481
Blinn-Phong模型
使用半程向量计算高光项
全局光照模型
还考虑间接光
光源模型
点,平行,面,发光物体等,略
裁剪空间与投影
原理略 P490
帧缓冲
引擎至少维护两个缓冲,分别用来扫描和计算
渲染管道
管道流程概览
工具阶段
定义建模,蒙皮,材质等
资产调节阶段
导出,处理,链接多种财产
将几何和材质数据处理成平台专用格式,直接载入内存
计算高级场景图,如BSP树
计算静态光照,辐射传输系数等
应用程序阶段
可见性判断
平截头体剔除
遮挡剔除(PVS)
入口与反入口
提交图元
参数
使用命令表与GPU进行交互
几何以及光栅化阶段
抗锯齿
SSAA,MSAA,MLAA,FXAA,详见P456
高级光照
基于图像的光照Image-based Lighting
法线,高度,凹凸,视差,位移,镜面,环境贴图等
全局光照GI
阴影渲染
模板缓冲
环境遮挡
预计算辐射传输PRT
延迟渲染Defered Rendering
G-buffer
视觉效果
粒子系统
贴花
环境效果
伽马修正
后处理
Chapter11 动画系统
类型
赛璐璐
刚性层阶
蒙皮动画
骨骼
层级结构
姿势
位置,定位和缩放(SQT格式)
动画
略
后期处理
反向动力学IK
已知末端位置求局部姿势,略
压缩与量化
插值与混合
Chapter12 碰撞与刚体动力学
物理与游戏
设计
不可预测,难调整,意外行为
工程
建设和维护成本高
建模需要更加谨慎
某些物理模拟需在服务器上进行
美术
需要参数,让工作更加困难
可能需要建立多版本
难以预测导致无法控制构图
碰撞/物理中间件
物理引擎
ODE,Bullet,PhysX,Havok,DMM
碰撞检测系统
碰撞体以及碰撞算法
略
隧穿问题
CCD
性能优化
数据结构,broad phase剪枝
刚体动力学
数值积分
显示欧拉法
误差高,稳定性低
后欧拉法
中点欧拉法
Runge-Kutta RK4
Verlet
速度Verlet
刚体
惯性张量
三维运动方程求解(P682)
碰撞响应
假设
碰撞的力作用于无限短时间
在表面上的切线方向无摩擦
单个恢复系数模拟能量损失
求解
还可以用惩罚力或碰撞约束模拟
摩擦力
略
休眠和岛屿
休眠条件
分岛屿进行休眠和唤醒,实现缓存一致性
约束
点对点约束point-to-potint constraint/ball and socket joint
刚性弹簧stiff spring constraint
铰链约束hinge constraint
滑移铰prismatic constraint
布娃娃
施力,力矩和冲量
物理步
游戏中的物理引擎
物理驱动与游戏驱动
物理驱动(dynamic)即完全由刚体动力学控制,游戏驱动则完全由玩家控制(key frame)
更新模拟
弹道
光纤来自摄像机焦点海上武器前端
碰撞几何体和渲染几何体是否匹配
手榴弹
为了保证玩家的控制力,要限制第一次落点后的运动幅度
爆炸
视觉效果,音效和其他动画和游戏系统
可破坏物体
角色控制
胶囊体phantom,可上阶梯,遇到墙有特殊行为
摄像机碰撞
略
高级物理功能
软体,布料,头发,流体力学,物理音频,GPGPU加速
Chapter13 音频
声音物理学
属性
瞬时声压
感知响度
感知响度正比于声压I,而I正比于声压均方根的平方
声压级SPL
其中Pref为听觉下限参考压强,一般取20Pa
等响曲线
可听频带20Hz-20kHz,超过该频带需要无限声压
传播
强度衰减
扩散模式
全向omnidirectional,锥形conical和单向wavefront
大气吸收
温度,适度等
叠加干涉
梳妆过滤
当声波被某表面反射时,某些频率会被完全抵消或强化
混响回声
直接,回声(一两次反射)与混响(多次反射叠加导致无法识别独立音色)
预延迟
收到直接声波与首个反射声波的间隔
衰变
反射声波完全消失所需的时长
多普勒效应
声音数学
信号基础知识
略
声音技术
模拟电子技术
麦克风
一种换能器transducer,将机械能转化为电压变化,有动圈式和电容式等
扬声器
通常有多个声道channel,甚至会有两个高音扬声器tweeter,超低音扬声器LFE
环绕声布局
放大器,增益控制器
数字音频技术
PCM采样,将连续信号转成离散,技术细节略(P745)
音频格式
无压缩:PCM,LPCM,WAV
有压缩:MP3,ATRAC,VAG
多声道
三维音频
建模
基于距离的衰减
Rmin Rmax之间按照1/r曲线衰减
根据实际情况
如潜行时加大,战斗时减小
偏移
采用恒功率偏移
3dB原则
保留余量,避免单个扬声器过载
中置可用于语音,提高音效区分度,但如果所有语音都中置则可能会覆盖其他声音
可以进一步把声源建模成圆弧在圆上的投影,分配于多个扬声器上
传播
几何分析,感知模型,即兴方法等
人为地为每个区域设置预延迟。衰变,密度等参数
区分阻断,障碍和排他的传播路径
音频引擎架构
硬件,驱动,API,引擎
处理管道
二维音(菜单,bgm,旁白)多通道,不经过混合器,三维音单声道
详见P770
音频存储和读取
形式:片断,音乐库
碎片:重定位
对于长时长的音乐,还可使用串流
混音后处理
目标
真实且不分散注意力,为游戏表现服务
分组
回避
实例限制
具体实现(P787)
背景音乐
根据情况播放不同playlist
事件发生叠加一小段stinger
Chapter14 游戏性系统
基本组成
世界元素
静态或动态
世界组块
内存限制或游戏流程控制
高级游戏流程high-level flow
游戏对象
游戏对象模型
指特定的面向对象编程接口,通常会拓展本身的编程语音
工具和运行时对象模型tool-side/runtime
数据驱动游戏引擎
全权交给美术或设计师,可提高团队效率
游戏世界编辑器
略
Chapter15 运行时游戏性基础系统
核心问题
运行时游戏对象模型
生命周期
与底层系统联动
模拟行为
新增类型
标识符,查询和引用
FSM
持久化(运行时类型识别,反射,抽象构造)
关卡管理和串流
更新实时对象模型
消息和事件处理
游戏流程管理
运行时对象模型架构
对象为中心架构object-centric
eg:《迅雷赛艇》
用合成或聚合替代继承;避免多重继承
组件模型
属性为中心架构property-centric
将属性按表存储,类似关系型数据库
纯组件模型
数据格式
二进制映像
无弹性,难以实时修改
不适合存储游戏对象,适合稳定的数据(网格)
序列化
xml,json
对于c++,需要实现反射系统
生成器
存储用于实例化和初始化游戏对象的数据
内存管理
加载
先加载LSR资产,再使用堆栈分配器加载和卸载关卡组块
为了防止加载新关卡造成等待,可设计阻隔室air lock组块(如狭小空间,通道,谜题等)
串流
划分区域来切割内存,使用基于内存池的内存分配器进行管理
区域之间有重叠,任意时刻查看玩家所在的组块列表并集,加载并卸载相应组块
碎片
为每个对象类型尺寸设内存池
内存重定位
存档
checkpoint或save anywhere
对象引用与查询
指针
容易产生孤立对象,过时指针和无效指针
智能指针
封装指针成对象,添加计数,GC核心
实现困难,可参考Boost
句柄
通过加入句柄表中间层,提高安全性和弹性
查询
一些加速查询的数据结构
散列表和二叉树
预先按条件建立对象列表
PS:C#GC相关可参考https://cloud.tencent.com/developer/article/1334938
实时更新游戏对象
性能考虑和合批更新
优势
缓存一致,减少重复运算,减少资源再分配,流水线并行
某些子系统根本不能以对象为单位更新,如碰撞检测
对象和子系统的相互依赖
为了解决依赖问题,游戏对象可在每个循环多次更新同个子系统
不是所有对象都需要多次更新,为了减少调用虚函数开销,可为每个更新函数配置对象链表;也可使用登记回调实现
对于对象之间的依赖,可建立森林,按层遍历
为了维持对象的状态一致性,查询对象需遵守桶规则
并行更新
异步思维,耗时操作采取非堵塞型函数
批处理思维
事件与消息泵
事件
封装事件
单个虚函数OnEvent即可处理
方便事件持久化,复制,广播,优先级队列等
事件类型
事件参数
登记接收事件
事件排队
数据驱动架构
略(P890)
处理
后期绑定/静态函数类型绑定
动态绑定,如C# delegate
脚本
游戏脚本特性
直译式,轻量,快速迭代,方便易用
典型游戏脚本
UnrealScript,Lua,Python
收藏
0 条评论
下一页