Unity整体性能优化篇 第(三)节:渲染优化 (GPU)

一:GPU与CPU的分工

GPU(显卡):负责渲染整个游戏的显示工作。

CPU:负责运算,游戏中的AI等等,同时为GPU的渲染做准备工作。

二:LOD层级细节

LOD介绍:LOD技术是通过摄像机所捕捉的视野范围来改变模型的层级切换,从而根据视野距离减少模型顶点,面的个数来达到渲染性能优化。

案例演示
1.例如我们有三个模型(细节不同,但都是木桶):

0号细节刻画较好
1号细节稍微次
2号几乎细节很低

GIF查看:
在这里插入图片描述

这时我们利用Lod Group添加这三个模型,根据摄像机捕捉视野范围进行切换该物体显示,在视野距离很远时使用2号物体,,在视野距离一般远时使用1号物体,在视野距离较近时使用0号物体,减少顶点渲染,同时Cast Shadow和ReceiveShadow可以移除根据情况,同时观察Stats面板的Batch数值;

2.Lod Group添加这三个模型:可见度100% 0号物体, 60% 1号物体 , 30% 2号物体
在这里插入图片描述
3.调整摄像机位置,注意观看Stats面板顶点Verts与面Tris的个数的变化。在这里插入图片描述
4.关闭Cast Shadow和ReceiveShadow,注意观看Batches(与DrawCall同值)的个数,不难看出关闭Cast Shadow和ReceiveShadow能减少DrawCall。在这里插入图片描述


三:遮挡剔除OcclusionCuling

视锥体剔除:

只渲染视锥体内物体,视锥体外不渲染。任何一个普通的camera都带有视锥体剔除的功能(系统默认),而且与物体是否static无关。

视锥体剔除能减少顶点Verts与面片Tris的个数,从而降低GPU的负担,和CPU的准备工作量,提高性能。
演示:注意看Statistics面板的数据改变

在这里插入图片描述

遮挡剔除:

近处大物体完全遮挡住远处的小物体,则对远处小物体的渲染是无用的,所以遮挡剔除远处小物体,这里要求物体static属性最少为Ocludder Static。

遮挡剔除步骤:

1.选中要渲染的物体,将其Static属性设置为Ocludder Static。

2.打开设置面板Window->Render->OcclusionCuling

3.选中面板的Visualzation,点击Bake.

4.选中Cameras,点击Bake

在这里插入图片描述

之后呢,我们视野中看到的大物体后面的小物体就会因为被遮挡而不被渲染,减少了渲染的顶点数,面数。
(由于我们设置了批处理,所以DrawCall的变化不明显,其实遮挡剔除也会影响DrawCall的)


四:光照贴图Lightmapping

光照贴图技术介绍:

使用静态烘焙光提前将光照信息制作成Lightmapping,减少因为实时光带来的drawcalls代价
以及所需渲染顶点的计算。

Lightmapping制作步骤:

1.首先确认渲染的物体,将其Static属性设置为LightMapStatic;

2.设置参与bake渲染光源mode为 baked;

3.window->lighting->点击Generate Lighting,生成光照贴图。

步骤GIF演示:
在这里插入图片描述

接下来我们发现DrawCall减少了,顶点以及面片渲染也少了。
在这里插入图片描述


五:Mesh合并

Mesh合并介绍:

Mesh合并是用于将一些拥有Mesh网格的物体进行合并为一个网格,会减少DrawCalls,减轻GPU负担,同时CPU对于GPU进行渲染前的准备工作也会减少(性能消耗减少)

Mesh合并步骤

1.将需要合并的物体统一放到一个空物体下

2.为空物体添加MeshRender与MeshFitter

3.编写脚本合并Mesh

4.合并成功后的网格赋予空物体,之后该空物体即是合并后的统一物体(可以直接删除合并网格的子物体)。
5.这时我们看到我们减少了近9个DrawCall

    void Start()
    {
        ChildMeshCombiner();
    }

    private void ChildMeshCombiner()   //子物体合并Mesh
    {
        MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
        CombineInstance[] combineInstances=new CombineInstance[meshFilters.Length-1];
        for (int i = 1; i < meshFilters.Length; i++)
        {
            combineInstances[i-1].mesh = meshFilters[i].sharedMesh;
            combineInstances[i-1].transform = meshFilters[i].transform.localToWorldMatrix;
        }

        var finalMater = meshFilters[1].gameObject.GetComponent<MeshRenderer>().material;
        Mesh finalMesh=new Mesh();
        finalMesh.CombineMeshes(combineInstances);
        meshFilters[0].mesh = finalMesh;
        GetComponent<MeshRenderer>().material = finalMater;
        
    }

编写好代码后演示过程(同时注意观看DrawCall数量):

在这里插入图片描述








项目工程链接地址(GitHub)

求github小星星哈,谢谢啦?
Unity性能优化项目工程链接:https://github.com/HanxianshengGame/Unity-Optimize-Project






--------------------------------------------------------我是有底线的-------------------------------------------------------------

    感谢能够观看博客的各位Unity开发爱好者们,有问题发表评论呐,★,°:.☆( ̄▽ ̄)/$:.°★

猜你喜欢

转载自blog.csdn.net/chongzi_daima/article/details/101381568