赞
踩
特殊文件链接
Unity3D研究院之手游开发中所有特殊的文件夹 | 雨松MOMO程序研究院
CPU和GPU的分工链接
Render - 浅谈 CPU 与 GPU 如何分工? - 知乎
脚本优化链接
MipMap与LOD是何物?_penchaoo-CSDN博客_mipmaplod偏移怎么调
知识补充:HZ:赫兹,刷新的频率。
比如显卡的赫兹是144,而显示器的帧率是60,那么帧率就会更不上显卡。每两帧渲染cpu的画面在屏幕上只能显示一帧,那么还有一帧的时候显示器就是黑的,只是太快了,看不出来。这时候就需要更好的显示器了。
但是一般,我们的手机60Hz就是极限了,再高你的屏幕也看不出来..
所以这时候就有垂直同步的概念了:设置一个项,把我们显卡的帧率和显示器的帧率做一个强行的同步(如果HZ不同步的话,画面会有撕裂感的,所以说要开垂直同步)。
1.Profiler
在unity的window下面可以打开profiler
点击运行之后 可以在左边面板选择你要监听的部分(可以看CPU,渲染,物理等等),右边第一个面板可以看到其占用情况的曲线
下面面板的左边可以看到不同函数,右边使其占用情况。
(当然了我这个面板选择的是cpu,你也可以选择别的去看看)
2.Statistics
FPS:渲染物体的数量和GPU性能的影响关系,如上图的数据770.0FPS(1.3ms),表示每帧的间隔为1.3ms,770.2帧。
CPU:占用CPU所用的时间
GPU:GPU渲染所用的时间
Batches(批处理):unity优化的而一种技术,类似于打包。打包的数量。基本上对应于draw call,这个是为了减少draw call的次数。(材质和shader会影响到这个Batches,如果都用同一个材质那么Batches就会变成1)
Saved by batching:节省的打包的次数。
Tris:三角形的数量。
Verts:顶点数(模型的数量)。
Screen:画面的分辨率。 同一行后面是这个是画面占用的显存的大小。
SetPass calls:unity中Shader里面调用pass的次数,如果这个越大那么渲染的压力越大
Shadow casters:影子的计算,比较消耗性能。
Visible skinned meshes:渲染的皮肤的网格的数量。(有皮肤(蒙皮)的网格)
Animations:unity中的animations。
draw call就是CPU调用GPU渲染的次数。
如果说drawcall一开始是一个一个调用格子的话,那么Batches批处理就是圈其中几个一起调用
而批处理又有静态批处理(Static),动态批处理等等。有的批处理的要求是要同一种材质。
美术资源优化:
一、模型
1.减少模型中那些没有用的面
2.合并模型,合并那些静态的模型和贴图。这样可以减少Draw Call的数量
3.LOD:建筑和复杂的物件用LOD模型和远处剔除来减少同屏面数。(比如吃鸡的里面那些树,你远处看看不清,近了才能看清)。
可以添加一个LOD Group的组件,但是记住下面Add的模型一定要是该物体的子物体。所以如果你想让他远处变成A,那你就要把A拖进来,变成他的子物体,然后再Add。
4.模型的重复利用
5.地形优化
二、材质
1.贴图大小
2.资源重复利用
3.小物件的贴图合并 (单个物品的贴图最好是一张,最多不易超过3张,相同贴图的材质球统一)
4.少用透明贴图,因为非常消耗GPU资源
5.minimap,跟LOD的效果差不多。节省GPU的消耗,但是会增加存储空间的大小。
6.小场景可以使用PBR材质,用了OBR就一定要用实时灯光才有效果。大场景尽量避免使用PBR材质,大场景可以用烘焙光影。
7.贴图压缩,对贴图进行PVRT(ios)或者ETC(Android)格式的压缩可以减少大量的内存消耗
三、灯光
1、灯光的数量:室外开放式大场景建议只用一盏平行光。室内场景可适当多一点,室内环境可以用reflection probe来加强反射效果。
2、场景烘焙:大场景和比较复杂的室内场景要避免实时灯光的使用。利用UNITY的烘焙系统把光影烘焙成贴图来实现光影效果。烘培贴图本身是一个浩大的工程,大场景的烘培可以选择性的去烘焙。UNITY里自动分UV功能不好控制,所以一般在max\Maya里分好第2套UV,也可以直接在max\Maya里烘焙好lightmap导入到unity里。
3.Unity提供了混合模式灯光,所以我们可以用混合灯光来实现LIGHTMAP与实时灯光结合。既:一个大场景中,大件如建筑、地形占据画面较大的物件烘焙lightmap,小物件繁多,占据画面的面积很小可以不用烘焙,把灯光设置为mixed模式.
四、其他
1.摄像机上少用镜头效果,要有选择性的使用。
2.特殊的shader慎用
=========================================================================
遮挡剔除:
效果:可以看到随着摄像机视野的不断往前,被挡住的部分就直接被剔除了。
对于大场景非常好用。
实现方法:
1.选中你要遮挡剔除得物体,然后选择Occludee Static
2.选中挡住剔除物的物体,然后设置为Occluder Static
3.打开window下的Occlusion Culling,然后点击bake烘焙。
4.选择隐藏模式,不要选Edit模式。(选了Edit模式你就看不见效果了(●'◡'●)
=========================================================================
光照烘焙
1.把光的Model设置成Baked
2.选中物体,将其勾选上Lightmap Static
3.在Window下的lighting下的settings下面去自动烘焙或者手动烘焙
4.效果对比
左边为我们烘焙的静态效果,右边为原来的动态光。
可以发现左边烘焙出来的效果更加好,但是不能移动物体(或者场景)了,如果移动的话,就会发现光影效果都是贴图,很假(就暴露了哈哈哈哈哈
=========================================================================合并mesh
效果
首先可以看到将所有物体合成了同一个物体,然后对应Statistics下面的话
1.Saved by batching由原先的114变成了0,因为原来由很多物体,然后批处理可以节约很多,但是现在变成了一个物体,所以没有节约的,就是单纯的对这个物体操作。
2.Shadow casters由原来的39变成了现在的1,因为原来是由很多物体叠加出来的,所以会有很多的shadow阴影,但是现在只有当前一个物体了,合并了,所有只有1。
实现方法:
1.首先将所有要合并的对象放在一个对象的子集下面
2.添加Mesh Conbine脚本,并且设置一个皮肤材质M,有个IsHideChild可以看效果。
Mesh Conbine.cs:
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class MeshCombiner : MonoBehaviour {
- public Material m;
- public bool isHideChild;
- void Start () {
- Combine();
- HideChild();
-
- }
-
-
-
- void Combine()
- {
- MeshFilter[] meshs = GetComponentsInChildren<MeshFilter>();
-
- CombineInstance[] combiners = new CombineInstance[meshs.Length];
-
- for (int i = 0; i < meshs.Length; i++)
- {
- combiners[i].mesh = meshs[i].sharedMesh;
- combiners[i].transform = meshs[i].transform.localToWorldMatrix;
-
-
- }
-
- Mesh target = new Mesh();
- target.CombineMeshes(combiners);
-
- //设置材质
- GetComponent<MeshFilter>().sharedMesh = target;
- GetComponent<Renderer>().material = m;
- }
- /// <summary>
- /// 隐藏子对象
- /// </summary>
- private void HideChild()
- {
- if (isHideChild)
- {
- var list = GetComponentsInChildren<Renderer>();
- foreach (var item in list)
- {
- if (GetComponent<Renderer>() != item)
- {
- item.enabled = false;
- }
- }
- }
- }
- }
3.添加Mesh Filter和MeshRenderer
=========================================================================
对象池
ObjectPool.cs:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ObjectPool : MonoBehaviour {
-
- public int poolCount = 30;
-
- public GameObject objPf;
-
- private List<GameObject> objList = new List<GameObject>();
- private void Start()
- {
- InitPool();
- }
- void InitPool()
- {
- for(int i = 0; i < poolCount; i++)
- {
- GameObject go = GameObject.Instantiate(objPf);
- objList.Add(go);
- go.SetActive(false);
- go.transform.parent = this.transform;
- }
- }
-
- public GameObject GetObj()
- {
- foreach(GameObject go in objList)
- {
- if (go.activeInHierarchy == false)
- {
- go.SetActive(true);
- return go;
- }
- }
- return null;
- }
-
- }
=========================================================================
关于脚本的性能优化:附上链接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。