前言
最近突然想了解一下游戏引擎中渲染部分是怎么优化的,所以在某平台上买了这本电子书,当初只是想了解行业技术,觉得翻译太浪费时间,所以买了这边。现在觉得这种选择是正确的,一本书看完,笔记还不到100条!这本书应该比较适合学习一段时间Unity后,作为进阶的入门材料。而如果想学一些渲染相关的优化,还是不推荐这本书的。
笔记
- 使用map时最好使用整型或enum做为 key,而不使用字符串
- 指针跳跃会浪费时间、因此删除或禁用空函数
- 经常使用的变量应该池化或使用引用、避免复制
- IO相关数据最好共享、避免重新加载
- 不需要每帧进行计算的函数使用协程(定时执行)
- 程序运行时优化:
- 将引用分配给预先存在的对象
- 使用静态类
- 单例组件
- 全局信息传递系统
- 单例模式对于管理共享资源或繁重的数据流(如文件、下载、数据解析和消息传递)非常有用
- 剔除不仅是渲染概念,在开发时的loop中剔除功能函数也可以提高性能
- 使用距离平方比使用距离更有优势,因为CPU擅长浮点运算、但不擅长平方根计算
- 在加载二进制文件时最好使用小块的序列化对象,并使用异步方式加载
- 应用程序需要在磁盘读取数据时,可以将数据缓存到内存中
- 对于关卡的加载,可以使用一个大的scene。 然后将scene分成若干场景块,在角色接近下一个关卡时(下一个场景块)异步加载
- 应避免CPU使用率抖动,将协程分配给每帧,而不是固定定时计算。目的是使CPU负载均衡。
- 渲染时,减少draw call,渲染状态变化越少越好。
- 音频瓶颈很多
- 过度压缩
- 过多音频操作
- 过多活动音频组件
- 低效的内存储存方法
- 访问速度
- 音频优化
- 最小化活动音源数量
- 禁止场景中冗余音源
- 为3D声音启用强制为单声道
- 将导入的音频文件重新采样到较低的频率将减小文件和运行时内存占用
- 最小化活动音源数量
- 压缩纹理
- https://docs.unity3d. com/Manual/class-TextureImporterOverride.html
- Dxt
- 纹理相关优化
- 减少纹理大小
- mipmap 产生时比原来增加33%
- 相机保持固定距离不会使用mipmap
- 使用图集、将小纹理打包。然后整合的draw call就会越多
- 谨慎使用
- 不要使用非2的n次方纹理、最好使用正方形纹理
- 运行时对磁盘访问会降低性能
- sparse textures
- 形成一个纹理包、连续从磁盘拉入
- 程序化纹理
- 异步纹理上传
- 网格压缩
- 把浮点数转换为固定值
- 降低顶点位置/法线的精度
- 简化顶点颜色信息
- 如果网格多边形足够少、存储大量顶点比蒙皮数据更好
- 合并网格
- 3D 物理引擎 physx
- 2D 物理引擎 Box2D
- 物理步长20毫秒
- 碰撞检测种类
- Discrete 离散
- 固定时长后断定2个物体碰撞、可能丢失碰撞
- continuous 连续
- 检测一个时间内是否有碰撞
- ContinousDynamic 连续动态
- Discrete 离散
- 碰撞器类型
- 球
- 胶囊体
- 立方体
- 网格
- 2D:圆、方框、多边形
- 网格碰撞器
* Convex凸
* Concave 凹 - 图形API默认使用两个帧缓冲区(尽管可以给自定义的渲染方案生成更多的帧缓冲区)。在任何时候,一个帧缓冲区包含渲染到帧中、并显示到屏幕上的数据;另一个帧缓冲区则在GPU完成命令缓冲区中的命令后被激活,进行图形绘制。
- 内存带宽.
- 如果需要的纹理已经存在于内核的本地纹理缓存中、采样会非常高效
- GPU每秒可提取1.6GB的纹理数据
- 如果着色器需要大量的纹理,很可能造成缓存丢失
- 使用前向渲染处理带有大量点光源的场景,将导致Draw Call计数呈爆炸式的增长
- 延迟着色的缺点就是无法独立管理抗锯齿、透明度和动画人物的阴影
- 顶点照明着色是光照的大规模简化处理,因为光照是按顶点处理而不是按像素处理
- 渲染过程分为三个
- 视锥剔除_对象是否可渲染
- 生成渲染对象指令
- 调用图形API发送指令到GPU
- 渲染性能增强
- 启用禁用GPU skinning
- 降低几何复杂度
- 减少曲面细分
- 应用Gpu实例化、
- 使用基于网格的LOD
- 拥有广阔视野和大量相机运动的场景有优势
- 室内场景或相机俯视视角无优势
- 剔除组
- 遮挡剔除
- 只适用静态网格
- 优化粒子系统
- 使用更少的粒子系统
- 生成更少的粒子
- 使用更少的特殊效果
- 粒子删除系统
- 避免粒子系统的递归调用
- 着色器优化
- 填充率和内存带宽两方面
- 纹理采样数量
- 使用的数学函数
- 使用移动平台算法
- 使用更低精度数据类型
- 重排时避免修改精度
- 减少数值计算复杂度
- 避免条件语句
- 减少数值依赖
sum=sum +1;sum=sum +2;
int sum1,int sum2; sum = sum1 + sum2;
- 使用基于着色器的LOD
- 使用更少的纹理数据
- 测试不同的GPU纹理压缩格式
- DXT、PVRTC、ETC、ASTC
- 最小化纹理交换
- 填充率和内存带宽两方面
- VRAM限制
- 可用VRAM数量
- 大多数从CPU到GPU的纹理传输都发生在初始化期间
- 异步初始化纹理时、先使用空白纹理
- 应该避免在运行时过于频繁地引入新纹理
- 预加载纹理
- 创建一个隐藏物体、当相机对物体见、将纹理从内存复制到VRAM中
- 避免纹理抖动
- 由于过多的纹理被加载到VRAM中、而当前帧需要的纹理不存在、会频繁覆盖、刷新VRAM中的纹理数据、产生内存碎片。和内存冲突
- 光照优化
- 谨慎地使用实时阴影
- 相对于硬阴影、软阴影并不会消耗更多的内存和CPU
- 使用剔除遮罩、限制给定对象光照的影响
- 烘焙光照纹理
- 在场景中烘焙光照和阴影对处理器的计算强度要低很多。
- 缺点是增加了应用程序的磁盘占用、内存消耗和内存带宽滥用的可能性
- 移动端优化
- 避免alpha测试
- 最小化draw call
- 最小化材质数量
- 最小化纹理大小
- 确保纹理是方形且大小为2的幂次方
- 着色器中尽可能使用最低精度格式
- VR 不适
- 运动晕眩
- 眼晴疲劳
- 迷失方向
- 可能导致癫痫发作
- VR性能指标
- 90 FPS或更高
- VR瓶颈是 GPU填充率
- 遮档剔除无意义
- VR两种渲染模式
- 单通道立体渲染
- 多通道立体渲染
- VR使用正向渲染、因为抗锯齿在后处理阶段更耗性能
- VR中法线贴图无法得到很好的效果、需要使用置换、细分、视差贴提升效果
- VR中景深、模糊、光晕效果不适用
- VR中背面剔除不好做、相机附近的物体最好不使用剔除、远外物体可使用
- VR中不使用欧拉角。四元数更好,可避免万向锁
总结
这本书应该偏入门些。对于现在的渲染需求。这里的所有优化方法都比较。。。 也可能我不是做Unity的吧!