1.锯齿产生的原因和应对方法?
光栅化阶段最重要的两个部分:三角形设置与遍历,片元着色器。
光栅化阶段执行片元着色器,,采色要么A要么B,导致边界区域颜色变化剧烈,而三角形的设置与遍历,会根据像素中心是否在三角形内部的原则,进行三角形的采样,使得锯齿明显。
抗锯齿的目标,就是让颜色变化的像素区域,有一些过渡色,不要过于生硬,在图形学中常用的如下:
1.超级采样抗锯齿 SSAA
光珊化阶段 执行更多的片元着色器,从高分辨率渲染,然后缩小到目标分辨率
2.多重采样抗锯齿 MSAA
光珊化阶段 每个像素多次采样进行平均,性能比SSAA好,但效果不如他好
3.快速近似抗锯齿 FXAA
后期对最终图像分析,检测锯齿和边缘走样,应用滤波器来减少锯齿效果,快速而低成本。但容易丧失细节和模糊
4.子像素采样抗锯齿 SMAA
后期对像素左侧和上侧边缘检测,又考虑了局部的像素对比,提取了更多的几何信息,保留了不该模糊的边缘。
5.帧间抗锯齿 TAA
后期加权混合多帧,将计算量分摊到多帧的超采样。
2.什么是多级渐远纹理Mipmap
mipmap是一组纹理的预渲染技术,提高纹理的渲染质量和性能,采用包含不同分辨率的图像,用于优化纹理在不同距离和大小上的显示效果。根据不同距离渲染合适纹理,提高性能。(有空看看闫课games101)需要额外 1/3 的空间来存储这些纹理。
3.A* 寻路算法优化策略
是静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越近,最终搜索距离越快,启发式算法。
避障的寻路算法有BFS DFS Dijkstar 而A*可以很快找到相对最优路径,搜索节点比前三个算法都要少。A*吸收了BFS和DFS的优缺点,寻找到的路优劣介于两者之间。
伪代码
优化策略: openlist 开放集合
五个操作降低时间复杂度,添加,删除,获取长度,判断是否存在,排序
让openlist排序稳定
getNeighbour获取当前按节点的邻居节点
获取邻居节点,这个函数相当于A* 的眼界。
扩大眼界,可以更容易找到更优路径,但计算节点也会变多
JPS跳点搜索算法,只支持允许走斜线的情况。对邻居节点进行剪枝,删去不必要的邻居。
F=G+H+C启发式函数
如果A*拐弯,通过增大C的值来增大F的值,一般把C函数加在G函数上。
注意可穿障碍物情况:在C函数在判断邻居节点是否是障碍物,如果是,就增加C的数值,从而达到增加F的目的。
map 地图
map矩阵优化,通过控制维度提升速度,矩阵越大意味着数据越多,通过合适的映射
分层优化提升速度 HPA 对map做一个预处理(在map很大的情况下适用)。
3.protobuf为什么效率高?
TLV算法(Tag-Length-Value)
wire type
Varint 使用变长编码压缩数值类型,值越小的数字,使用越少的字节数表示
ZigZag
Length
packed
默认值
压缩算法
4.换装原理和实现
美术模型导入unity会转换为transform形式的节点,一般名带root表示根骨骼,animation记录每帧对应动作的骨骼的position或者scale ,每帧连成整体就是动画,K帧,可以把模型理解为两块组成mesh和材质。
mesh中的boneWeights属性对应每个顶点所对应的骨骼和权重。
mesh中使用的骨骼变换矩阵记录在bindpose中。
LBS蒙皮算法
按照是否蒙皮影响换装分为两类:
不影响:更换材质,骨骼挂接 影响:共享骨骼,mesh合并(unity推荐的方式)
不影响:
更换材质,通常为时装染色
骨骼挂接,预先在骨骼下添加一个节点然后动态更换指定物件即可
没有动作的骨骼挂接:适合武器,背饰等 有动作的骨骼挂接:适合坐骑
影响:
对换装部位进行蒙皮,将主骨骼附上动画组件,模型动画控住主骨骼,同时将需要换的部件加载到主骨骼上,然后将每个部件上的SkinnedMeshRenderer所影响的骨骼替换为主骨骼上的同名骨骼,即可达到动态蒙皮的效果,这就是共享骨骼。
unity官方推荐:Mesh合并
在共享骨骼的基础上进行优化,合并skinnedmeshRenderer
合并相同材质的材质球,合并材质,重新计算UV
~~~很多细节~~
四元数和欧拉角
四元数(一个4维的四元数)可以避免万向锁和提供平滑插值。
欧拉角(物体绕坐标系三个坐标轴的旋转角度)旋转顺序Y-X-Z,但是会有万向锁的问题。
unity脚本生命周期与执行顺序,什么是协程?
Awake - OnEnale - Start - Update - FixedUpdate - LateUpdate - OnGUI - OnDisable - OnDestroy
协程不是线程,协程的实现原理是迭代器,而迭代器实现原理是状态机。
RectTransform和Transform的区别
rectTransfrom是Transform的子类,也是继承transfrom的,
Unity中碰撞器和触发器的区别,Collider和Trigger
collider有碰撞效果,is Trigger = false ,可以调用OnCollisionEnter/stay/Exit函数
trigger没有碰撞效果,is Trigger = true,可以调用 OnTriggerEnter/Stay/Exit函数
物体发生碰撞的必要条件?
有collider碰撞器和rigidbody人物的刚体属性。
CharacterController和rigidbody的区别?
rigidbody有完全真实的物理特性,而charactercontroller 则是受限的rigidbody,具有一定的物理效果但不是完全真实。
物体发生碰撞时
三个阶段 对应函数: onCollisionEnter/ Stay/ Exit
两种施加压力的方式 : rigidbody.AddForce/ AddForceAtPosition 都是rigidbody的成员函数
光源
directionlight,arealight,pointlight,spotlight
物理更新在哪个系统函数里?
fixedupdate函数中,fixedupdate可以保持固定的时间间隔调用,某些需要在时间上精确模拟的任务需要放在里面。
移动相机动作在哪个函数里,为什么在这个函数里?
lateupdate是所有update结束后才调用, 比较适合于命令脚本的执行。
简述一下Prefab的用处?
游戏运行时实例化,对已有的素材,脚本,参数做一个默认配置,以便于后面的修改,同时prefab打包的内容简化了导出的操作,便于团队交流
如何安全的在不同工程间迁移asset数据,三种方法
1.将asset和library一起迁移 2.导出包package 3.用unity自带的assets Server功能
移动相机动作在哪个函数里,为什么在这个函数里?
lateUpdate,是在所有的Update结束后才调用,比较适合于命令脚本的执行。官网上例子是摄像机的跟随,都是所有的update操作完才进行。
GPU的工作原理 : 顶点处理,光栅化计算,纹理贴图,像素处理,最终输出。
什么是渲染管道 :显示器为了显示出图像而经过的一系列必要操作。
如何优化内存? 压缩自带类库,将常用但是暂时不用的物体隐藏起来而不是Destroy,释放AssetBundle占用的资源,降低模型的面数,使用光照贴图,多层次细节(LOD),着色器(Shader)和预设(Prefab)
动态加载资源的方式:Resource.Load(); / AssetBundle
游戏动画有哪几种,及其原理? 关节动画,骨骼动画,单一网格模型动画(关键帧动画)
LOD技术及其优缺点? level of detail 按照模型的位置和重要程度决定物体渲染的资源分配。
当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况? 穿透(碰撞检测失败)
什么是动态合批和静态合批?
动态批处理一切都是自动的,不需要任何操作, 静态批处理自由度很高,限制很少,占用更多内存,而且经过静态批处理物体不可以再移动了。
什么是LightMap?
三维软件里打光,通过渲染把场景各表面的光照输出到贴图上,最后通过引擎贴到场景上,使得物体有了光照的感觉
相机clipping planes的作用?调整near fare两个值应该注意什么?
剪裁平面,从相机开始渲染到停止渲染之间的距离。
降低drawcall 的技术是draw call batching
将Camera组件的ClearFlags 选成Depth only什么意思
仅深度,用于对象不被剪裁
如何让已经存在的GAMEObject在LoadLevel后不被卸载?
void awake(){ DontDestroyOnLoad(transform.gameObject); }
drawcall?
每次引擎准备数据并通知CPU的过程称为一次Draw Call , Draw call 越高,显卡性能消耗越大
降低Drawcall的方法:Dynamic Batching Static Batching 高级特性的Shader降级为统一的低级特性的Shader
水面倒影?
对水面的贴图纹理进行扰动,产生波光粼粼的效果,用shader可以通过 GPU在像素级别作扰动,效果细腻,需要的顶点少,速度快
Unity实现跨平台的原理?
通过Mono虚拟机实现的,通过Mono将C# -> CIL mono运行时利用JIT或者AOT(IOS限制,直接编译为ARM汇编代码)将CIL编译成目标平台的原生代码实现。 IL是intermediate Language的缩写
游戏本质是由交互序列组成的,基础结构,
while(true){
Input();
Update();
Render(); }
循环由三部分组成 1.非阻塞的用户输入 2.更新游戏逻辑状态 3.渲染游戏画面
每次循环完会更新一帧画面。
一般会有期望的固定帧率模式,如果每帧运行时间短,帧率超过预定标准,加入延期等待。
掉帧只运行逻辑,不绘制画面,用省下来的时间来追赶落后的帧
时间记录
游戏实时反馈系统涉及各种时间,人物行走的位移计算,战斗中的延迟伤害。一般分为真实时间线和游戏时间线,呼出菜单就暂停
动画事件
显示型事件,时间型事件,显示例如开枪动画与行走动画混合,时间例如攻击同时触发伤害,UGUI是射线检测还是计算坐标?计算坐标,但射线检测的情况是...
游戏同步
通信方式 C/S P2P架构 数据模式 全网状数据模式/星型数据模式 同步方式 状态同步/帧同步
协程的底层原理
IEnumerator是什么? yield和 IEnumerator什么关系? 为什么yield return能停住代码
FSM的原理
FSM是一种状态转换图,由一组状态节点和一组转换条件组成,非常有用的编程模式,可用于控制对象的行为。首先创建一个状态积类,然后在玩家的update方法中,根据当前状态执行不同的行为,最后在fixed update方法中,根据输入事件触发不同的转换条件,使角色从一个状态节点转换到另一个状态节点。
贴图有哪些?
固有色贴图 透明贴图 AO贴图 高度贴图 法线贴图 高光贴图 发光贴图 渐变贴图 噪声贴图(云朵,火焰,大理石,天然木材等)
UV滚动?流光效果?
表面效果中很常见,兼顾了多边性和低性能消耗的特点,广泛应用。
误移动文件检测
渲染管线
顶点着色器,曲面细分,几何着色器,变化回执,裁剪,屏幕映射,图源装配,光栅化,提前深度测试,片元着色器,逐片元操作
不透明或者半透明物体的显示状态如何确定?
画家算法 深度缓冲区 渲染队列 延迟渲染
Texture图片空间和内存占用 常用压缩
前向渲染,延迟渲染