DrawCall是渲染管线的一部分,渲染管线就是绘制图像的流程,具体渲染管线和DrawCall是什么我引用一位博主的文章,讲的很清晰,可以去原地址查看
CPU通过调用图形API接口( glDrawElements (OpenGl中的图元渲染函数) 或者 DrawIndexedPrimitive (DirectX中的顶点绘制方法) )命令GPU对指定物体进行一次渲染的操作即为DrawCall。此过程实质上就是在告诉GPU该使用哪个模型的数据(图形API函数的功能就是将CPU计算出的顶点数据渲染出来)。
链接: Unity3D 渲染管线全流程解析
原理:CPU在提交DrawCall的时候,一个mesh和一个texture就对应一次DrawCall,两个mesh一个texture对应两次DrawCall,所以减少DrawCall一般从这两个方面入手,将多个mesh合并成一个,或者用图集将多个texture合并成一个
Unity静态批处理是一种优化技术,用于在渲染过程中减少绘制调用的数量。在Unity中,每个游戏对象都有一个MeshRenderer组件,用于渲染该对象的网格。当场景中有大量的游戏对象时,每个对象都需要进行一次绘制调用,这会导致性能下降。
静态批处理的目的是将多个游戏对象的网格合并成一个大的网格,然后一次性绘制。这样可以减少绘制调用的数量,提高渲染性能。Unity的静态批处理功能可以自动将静态的游戏对象进行批处理。要启用静态批处理,可以在Unity的Player Settings中勾选"Static Batching"选项。
注意事项:静态批处理的物体需要勾选static状态,并且不能移动
如果物体要移动,可以考虑使用动态批处理,但是动态批处理限制条件很大,并且适用于大量物体的渲染,对于少量物体的渲染可能没有明显的性能提升。
Unity的GPU实例化(GPU Instancing)是一种渲染优化技术,可以在GPU上复制和重用渲染数据,从而减少CPU到GPU的数据传输和渲染调用次数,提高性能。使用GPU实例化可以将多个相同的物体实例化为一个批处理,这些物体可以共享相同的材质和渲染属性。可以一次性渲染多个实例化物体,而不是每个物体都进行单独的渲染调用。使用时在材质上勾选GPU Instancing即可
手动将多个mesh合并成一个大的mesh,适用于大型静态场景,能起到跟static batch差不多的效果。
示例代码:将代码挂载到父物体上,运行时便会自动合并所有子物体的mesh
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class ExampleClass : MonoBehaviour
{
void Start()
{
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
int i = 0;
while (i < meshFilters.Length)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
meshFilters[i].gameObject.SetActive(false);
i++;
}
transform.GetComponent<MeshFilter>().mesh = new Mesh();
transform.GetComponent<MeshFilter>().mesh.CombineMeshes(combine);
transform.gameObject.SetActive(true);
}
}
在Unity中,Atlas(图集)是一种将多个小纹理(Texture)合并成一个大纹理的技术。使用图集可以减少渲染调用次数,提高性能和内存利用率。打包图集以后需要使用uv坐标来确定当前材质需要使用的texture
跟texture atlas使用方法差不多,不过sprite atlas适用于UI元素
贴图的分辨率和最终渲染出来的分辨率是不一样的,根据近大远小原理,远处的物体会缩小,所以对应的贴图也会被缩小,此时会导致模糊,闪烁(摩尔纹效应) 等问题,mipmap是一种根据渲染距离,使用不同大小贴图的技术,不仅能解决上述问题,还能减少性能开销。
Mipmap的创建和使用是自动的,只需在纹理导入设置中启用Mipmap选项即可。当Mipmap被启用时,Unity会在导入纹理时自动生成一系列缩小版本的纹理。这些缩小版本的纹理分别是原始纹理的1/2、1/4、1/8…分辨率大小。
注意事项:使用Mipmap会增加纹理的内存占用,因为它包含了多个缩小版本的纹理。
多级模型技术,类似于mesh版的mipmap,比如有一个房子,上面有窗台,花盆等细节,当玩家距离较远的时候,再显示这些细节就没有必要了,反正玩家也看不到,这个时候把这些细节删去也几乎不影响效果。
在Unity中,LOD(Level of Detail) Group是一种功能,允许开发者管理和控制场景中物体的细节级别。LOD Group是一个可以添加到游戏对象上的组件,它包含多个LOD级别。
每个LOD级别代表了对象的不同细节级别。例如,第一个LOD级别可能是一个高度详细的模型,而第二个LOD级别可能是一个简化版本,具有更少的多边形。随着相机与物体之间的距离增加,Unity会自动切换到适当的LOD级别,以保持性能。
刺客信条大革命中实现同屏上万NPC就用到了类似的技术,B站有翻译好的视频,非常建议看一下,另外提一嘴,GDC游戏开发者大会,英语全称为 Game Developer Conference,是一年一度的游戏开发者最大的聚会,每年将有数万名游戏开发者参加大会。GDC上有很多大佬讲的游戏方面的知识,质量都很高,其他的视频也可以看一看。
链接: 【中英双字】《刺客信条:大革命》中的同屏上万NPC是如何实现的「GDC」
首先要讲一下UGUI中canvas更新的原理,系统会检测当前canvas上是否发生了变动(比如鼠标放到某个按钮上,按钮的颜色发生改变),如果有变动,就会刷新整张Canvas。我们可以考虑使用多个canvas,同一个界面下的UI,可活动的元素放在一个Canvas下,不可活动的元素放在另一个Canvas下,这样就只会刷新活动canvas的页面,减少的性能消耗。
这块我了解不是很深,这里先借用ChatGpt的回答
Unity SRP Batcher是Unity的一种渲染技术,它是在Unity的脚本化渲染管线(Scriptable Render Pipeline,SRP)中的一部分。SRP Batcher旨在提高渲染性能,通过减少CPU到GPU之间的数据传输和渲染状态切换来优化渲染过程。
SRP Batcher通过将多个渲染调用打包成一个批次来实现性能优化。在传统渲染中,每个渲染调用都会导致一次CPU到GPU的数据传输和渲染状态切换,这会带来较大的开销。而SRP Batcher会将多个渲染调用打包成一个批次,然后一次性传输数据和进行状态切换,从而减少了开销。
使用SRP Batcher可以提高游戏的渲染性能,特别是在处理大量渲染调用时。它可以与Unity的各种渲染特性和效果一起使用,并且可以通过自定义SRP进行扩展和优化。
总之,Unity SRP Batcher是Unity中的一种渲染技术,通过打包渲染调用以减少CPU到GPU之间的数据传输和渲染状态切换来优化渲染性能。
游戏中使用的图片的宽和高尽量设置为2的幂,这样能保证图片的大小是二的幂字节。因为cpu和gpu一次性能处理的字节数是二的幂,例如cpu一次性能处理8个字节,而图片大小为9个字节,那么就要两个周期来处理,仅仅多了一个字节却要浪费掉一个周期。
减少顶点数量,减少材质数量,减少shader数量(SetPass)等
性能优化这块内容比较多,如果每一个都贴上代码讲如何使用,将耗费巨大的精力,本文只是列一个提纲,更深入的内容请大家自行学习,可以结合上文将的Profiler工具一起使用