unity如何得到所有子对象_Unity用户手册-Mesh合批
Mesh合批
把很多静止的模型,标记为Batching Static,原本需要把模型一个个送到GPU渲染,Unity会把相同材质相同纹理相同Shader的模型合批成一个大的模型,送到GPU进行渲染,这样就减少DrawCall。可以调用Mesh.CombineMeshes方法,创建CombineInstance[]数组,进行合批。
Static Batching
要求:必须使用相同的材质material,相同的纹理Texture,然后在编辑器里设置为static batching的。
特点:静态批是无法运动的。
所以一般制作流程上,对于场景这些静态的物体都采用静态批,美术会根据场景的规模,将相邻的一片物件的贴图合并到一张或几张1024或512的大图上,这样这些物件可以使用同一个material,就可以静态批在一起,大幅节省DrawCall。 静态批的时候Unity3d会在运行时生成一个合并的大模型,并且为这个模型指定一张共同的贴图,所以这个批在一起的数量是有限的,如果批在一起的定点数过多,它就会自动分成两个批,一个静态批的上限为65535,这是因为Unity默认使用16位Mesh Index Buffer。
详情请阅读 :https://docs.unity3d.com/ScriptReference/Rendering.IndexFormat.html
Dynamic batching
Dynamic batching的原理也很简单,在进行场景绘制之前将所有的共享同一材质的模型的顶点信息变换到世界空间中,然后通过一次Draw call绘制多个模型,达到合批的目的。模型顶点变换的操作是由CPU完成的,所以这会带来一些CPU的性能消耗。并且计算的模型顶点数量不宜太多,否则CPU串行计算耗费的时间太长会造成场景渲染卡顿,所以Dynamic batching只能处理一些小模型。
要求如下:
- 目前Unity限制能进行Dynamic batching的模型最高能有900个顶点属性。这里注意不是900个顶点,而是900个顶点属性。如果我们在Shader中使用了Vertex Position,Normal and single UV,那么能够进行Dynamic batching的模型最多只能够有300个顶点。如果我们在Shader中使用了Vertex Position、Normal、UV0、UV1 and Tangent那么顶点的数量就减少到180个。
- 批在一起的所有的模型应用同样的缩放值
- 使用相同的材质
- 相同的一张lightmap
- 不能使用多pass的shader
- 不能接收阴影
DrawCall
DrawCall是CPU通过底层图像编程接口发出的渲染命令,GPU读取渲染命令执行渲染操作。
过多的DrawCall影响绘制的原因:
主要是每次绘制时,CPU通过底层图像编程接口发出渲染命令DrawCall,而每个DrawCall需要很多准备工作,检测渲染状态、提交渲染数据、提交渲染状态,而GPU本身可以很快处理完渲染任务。DrawCall过多,CPU负载过多,而GPU性能闲置。
渲染状态
渲染状态定义场景中的网格是怎样被渲染出来的。例如使用哪个顶点着色器、哪个片元着色器、光源属性、材质等。如果没有更改渲染状态,所有的网格将使用同一种渲染状态。
Mesh.CombineMeshes方法
- 遍历当前对象和子对象的MeshFilter组件,创建CombineInstance[]数组。
- 获取filter.sharedMesh赋值给combine[i].mesh。
- obj.transform.worldToLocalMatrix * filter.transform.localToWorldMatrix得到当前对象和子对象在本地空间的矩阵,赋值给combine[i].transform。
- 遍历子对象所有的MeshRenderer组件,获取render.sharedMaterial存储在一个List中,然后赋值给当前对象的MeshRenderer的sharedMaterials。
- 调用mesh.CombineMeshes(combine),合并Mesh。
- 同时,还可以调用Unwrapping.GenerateSecondaryUVSet(meshFilter.sharedMesh);合并第二套UV。
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;public class CombineMesh
{private const string MESH_PATH = "Assets/GameData/";[MenuItem("Examples/CombineMesh")]static void Combine(){GameObject obj = Selection.activeGameObject;if (obj.GetComponent<MeshRenderer>() == null){obj.AddComponent<MeshRenderer>();}if (obj.GetComponent<MeshFilter>() == null){obj.AddComponent<MeshFilter>();}List<Material> material = new List<Material>();Matrix4x4 matrix = obj.transform.worldToLocalMatrix;MeshFilter[] filters = obj.GetComponentsInChildren<MeshFilter>();int filterLength = filters.Length;CombineInstance[] combine = new CombineInstance[filterLength];for (int i = 0; i < filterLength; i++){MeshFilter filter = filters[i];MeshRenderer render = filter.GetComponent<MeshRenderer>();if (render == null){continue;}if (render.sharedMaterial != null && !material.Contains(render.sharedMaterial)){material.Add(render.sharedMaterial);}combine[i].mesh = filter.sharedMesh;//对坐标系施加变换的方法是 当前对象和子对象在世界空间中的矩阵 左乘 当前对象从世界空间转换为本地空间的变换矩阵//得到当前对象和子对象在本地空间的矩阵。combine[i].transform = matrix * filter.transform.localToWorldMatrix;render.enabled = false;}MeshFilter meshFilter = obj.GetComponent<MeshFilter>();Mesh mesh = new Mesh();mesh.name = "Combine";//合并Meshmesh.CombineMeshes(combine);meshFilter.sharedMesh = mesh;//合并第二套UVUnwrapping.GenerateSecondaryUVSet(meshFilter.sharedMesh);MeshRenderer renderer = obj.GetComponent<MeshRenderer>();renderer.sharedMaterials = material.ToArray();renderer.enabled = true;MeshCollider collider = new MeshCollider();if (collider != null){collider.sharedMesh = mesh;}string tempPath = MESH_PATH + obj.name + "_mesh.asset";AssetDatabase.CreateAsset(meshFilter.sharedMesh, tempPath);PrefabUtility.DisconnectPrefabInstance(obj);}}
对坐标系施加变换的方法
矩阵变换,当前对象和子对象在世界空间中的矩阵 左乘 当前对象从世界空间转换为本地空间的变换矩阵,得到当前对象和子对象在本地空间的矩阵。
unity如何得到所有子对象_Unity用户手册-Mesh合批相关推荐
- unity烘培单个物体_Unity可编程渲染管线(SRP)教程:二、自定义着色器
本文翻译自Catlike Coding,原作者:Jasper Flick. 本文经原作者授权,转载请说明出处. 原文链接在下: https://catlikecoding.com/unity/tuto ...
- unity android 在后台运行_Unity问答 | 盘点2019年社区优秀问答
Unity社区创建以来便成为广大Unity开发者与创作者的经验分享以及技术交流的平台,社区成员互帮互助,分享个人开发心得的同时,也积极踊跃地在社区提出自己遇到的开发难题. 2019年,Unity Co ...
- unity scence灯光不显示_Unity基础教程系列(四)——多场景(Loading Levels)
目录 1 池场景 1.1 在运行时创建场景 1.2 把对象放入场景池 1.3 从重编译中恢复 2 关卡1 2.1 多场景编辑 2.2 场景灯光 2.3 在构建中包含多场景 2.4 加载场景 2.5 等 ...
- dll放在unity哪个文件夹下_unity调用C#dll文件
<一>.创建dll文件 1,打开vs文件->新建-> 项目->C#->类库,输入项目的名称,创建一个dll项目; 2,引入 UnityEngine UnityEdi ...
- 【Unity】导航基本组件:Nav Mesh Agent、Off Mesh Link、Nav Mesh Obstacle
文章目录 Nav Mesh Agent 导航网格代理 属性 Off Mesh Link 网格外链接 属性 链接是否成功 静态障碍物和动态障碍物 静态障碍物 动态障碍物 Nav Mesh Obstacl ...
- unity透明通道加颜色_Unity SRP 6.透明
翻译汇总文章: HipHopBoy:Unity SRP 系列翻译汇总zhuanlan.zhihu.com 原文链接: https://catlikecoding.com/unity/tutorial ...
- 【Unity】Unity插件:地形编辑器MTE(Mesh Terrain Editor)
文章目录 地形编辑器MTE 下载方式 文档及教程 主要功能 地表类型 创建工具 示例文件 创建地图 绘制地图 快捷键 提升.降低高度 绘制高度 平滑高度 绘制纹理 细节问题处理 地形编辑器MTE MT ...
- unity给头发添加物理_Unity学习笔记 Vol.64 使用Spring Bone给角色添加头发效果
摘要 在游戏中,让我们的角色拥有一头柔顺的秀发,可以使角色显得更加生动.在UnityChan模版我们可以从中借鉴Unity酱的飘逸的头发的实现方法.下面我们来具体研究一下. 实现方法 UnityCha ...
- unity给头发添加物理_unity游戏角色发型头发设计毛发毛皮纹理胡子生成编辑插件Hair Designer v1.5.7...
Hair Designer是角色发型头发和毛发毛皮纹理胡子设计生成编辑插件,包括可自定义的着色器. Hair designer is an amazing tool for generating dy ...
最新文章
- java开发checklist,Java API设计CheckList
- PHP实现文件安全下载
- springboot入门_模板
- S5PV210裸机之GPIO
- python计算近似圆周率
- IOS--多线程--GCD--在CGD中快速实现多线程的并发控制
- eclipse目录改名,子目录及JAVA文件同步更改
- Android系统移植与调试之-------如何修改Android手机显示的4G信号强度的格子数
- 系列学习 Gateway 之第 1 篇 —— SpringCloud Gateway 简介,Gateway 入门实例
- mindmanager 15 停止工作
- 查看是否是固态硬盘SSD
- python六芒星怎么画_Python Turtle绘画初学编程——六芒星,浪形圈
- MAC系统字体库存放目录
- 秋招面试问题总结-视觉算法
- Debian 安装 git
- GridView-adaper控件设置边框-边距-实现分割效果
- SVN管理工具Cornerstone之:创建分支、提交合并
- 烦心事一件接着一件,此起彼伏
- php云盘实现上传下载,文件上传功能-PHP通过数据库实现在线网盘管理文件上传下载-PHP中文网教程...
- 如何绕过校园网验证,在宿舍免费上办公区的网,享受不拥挤的网络