163 lines
4.5 KiB
Markdown
163 lines
4.5 KiB
Markdown
---
|
||
aliases:
|
||
tags:
|
||
creation date: 2025-01-04 11:22
|
||
modification date: Saturday 4th January 2025 11:22:39
|
||
---
|
||
# Games101
|
||
## 顶点着色器
|
||
### 数据输入
|
||
- 顶点布局
|
||
- 每个顶点独有,且渲染中不变的数据
|
||
- 模型顶点坐标、uv贴图、蒙皮骨骼
|
||
- 可变独占
|
||
- 每个顶点独有,直接映射为纹理,通过uv坐标访问
|
||
- 共享资源
|
||
- 每个顶点共享,经常变化的数据
|
||
- MVP矩阵 、光照信息
|
||
### 空间变化
|
||
考虑相同模型的不同物体
|
||
- 模型空间
|
||
- [x] 来自美术提供的源文件,共用同一份GPU顶点缓冲区
|
||
- [ ] 加载模型骨骼动画,顶点蒙皮缓冲区
|
||
- 动画空间
|
||
动画可以不一样,动画进度也可以不一样
|
||
- 骨骼动画
|
||
- CPU更新每根骨骼的位置
|
||
- 加权计算蒙皮骨骼变换
|
||
- 一个顶点加权4根骨骼就够了
|
||
- 纹理动画
|
||
- 普通关键帧动画
|
||
- 骨骼动画烘培成纹理动画
|
||
- MVP矩阵
|
||
- 世界空间
|
||
- 模型变换矩阵 * 动画矩阵
|
||
- 对单位向量进行变换,计算很方便
|
||
- 模型坐标、模型xyz旋转、模型缩放
|
||
- M = T * R * S , 先缩放,再旋转,最后平移
|
||
- 如何计算xyz旋转矩阵呢?
|
||
- 固定一个轴,然后计算另外两个轴旋转后的坐标,能直接写出绕轴的旋转矩阵
|
||
- 三个矩阵相乘就是最终旋转矩阵,顺序呢?UE是先Z再X再Y
|
||
- 相机空间
|
||
- 相机透视矩阵 * 世界空间
|
||
- 要变换回单位向量,计算很复杂
|
||
- 可以放过来求逆
|
||
- 单位向量进行变换
|
||
- 正交矩阵的逆是矩阵转置
|
||
- 单位向量依然是单位向量
|
||
- 单位向量依然互相垂直
|
||
- 正交矩阵只改变了单位向量的方向
|
||
- 相机坐标、相机朝向、相机UP方向
|
||
- 相机朝向要变为-z方向,up方向要变为y方向
|
||
- x 方向由 -z 和 y 叉乘得到
|
||
- 投影空间
|
||
- 相机投影矩阵 * 相机空间
|
||
- 正交投影
|
||
- 相机空间投影到立方体[-1,1]^3
|
||
- 要变换回单位向量
|
||
- 先平移再缩放
|
||
- 透视投影
|
||
- 正交投影矩阵(线性) * 透视投影矩阵(非线性)
|
||
- 非线性变化特点
|
||
- 把四棱锥挤压成长方体
|
||
- 压缩有一个系数比n/z,三个坐标都有变化,z坐标变化未知
|
||
- z坐标在近平面和远平面,需要保持z不变
|
||
- 列出方程,求解矩阵
|
||
- An + B = nn
|
||
- Af + B = ff
|
||
- n 0 0 0
|
||
- 0 n 0 0
|
||
- 0 0 n+f -nf
|
||
- 0 0 1 0
|
||
- MVP矩阵 = 相机投影矩阵 * 相机矩阵 * 模型矩阵(TRS)
|
||
## 光线追踪
|
||
### 空间划分
|
||
- 网格
|
||
- 体素游戏
|
||
- 实现简单,空间开销大
|
||
- 寻路方便、划分简单
|
||
- 四叉树、八叉树
|
||
空间划分成四/八份, 检测子空间物体数量,数量太多就递归划分子空间
|
||
- 和维度相关,分叉太多
|
||
- 跨节点物体存储浪费
|
||
- 动态物体会频繁变更节点树
|
||
- BSP树
|
||
二叉树,每次使用超平面分割空间,分割时采取空间或物体均匀划分
|
||
- 构建复杂,适合室内场景优化
|
||
- 不适合处理动态物体,需要重新构建BSP树
|
||
- KD树
|
||
- 超平面是轴对齐的特殊BSP树
|
||
- BVH树
|
||
### 数学算法
|
||
- 判断点和平面的关系
|
||
|
||
# 多线程
|
||
|
||
手机端,多线程拆分太细,会导致新的问题发热、耗电快
|
||
|
||
所以当任务量较小时,应该退化为单线程
|
||
|
||
## 实现
|
||
|
||
### 任务
|
||
|
||
- 对任务进行封装,变成一个可执行单元
|
||
- 从线程池获取线程,执行任务
|
||
- 线程调度,优先级、CPU大小核
|
||
|
||
### 线程安全
|
||
|
||
- 原子操作
|
||
- std::atomic
|
||
- 加锁
|
||
- 无锁
|
||
- 如果操作是线性的
|
||
- 可以使用CAS循环操作
|
||
- 同步、异步
|
||
- 条件变量、信号量
|
||
|
||
## 任务
|
||
|
||
### IO
|
||
|
||
- 我希望序列化的对象内存都是临时内存
|
||
- 序列化要有一个单独的内存分配器
|
||
|
||
### 渲染
|
||
|
||
- 封装记录API命令,然后再交给渲染线程
|
||
- 只能降低api调用耗时,但是现代api开销没那么大
|
||
- 复制对象状态,传递给渲染线程绘制
|
||
- 空间换时间,性能更好
|
||
- 可见性检测、批处理、api调用
|
||
|
||
## 粒子
|
||
|
||
|
||
|
||
### 物理
|
||
|
||
### 动画
|
||
|
||
## Job系统
|
||
|
||
- 比如物理线程中,可以一次开多个小线程,并行计数,然后等待计算结果
|
||
|
||
|
||
|
||
## 内存管理
|
||
|
||
- 初始化后,大小不变的堆数组
|
||
- 需要快速申请、快速释放
|
||
- 存储相同子类型的特殊数组
|
||
- 顶点缓冲区
|
||
- 存储子类型的特殊数组,要求访问连续
|
||
- 帧缓存区、全局缓冲区、可回收缓冲区
|
||
|
||
## 异步回调
|
||
|
||
- 这样对异步资源需要进行封装
|
||
- 需要能让资源还能正常组装,而没有深度依赖
|
||
- 需要知道何时加载完毕
|
||
- 可以由异步切换到同步
|