当前位置:网站首页>Unity3D学习笔记5——创建子Mesh
Unity3D学习笔记5——创建子Mesh
2022-07-07 21:50:00 【charlee44】
1. 概述
在文章Unity3D学习笔记4——创建Mesh高级接口通过高级API的方式创建了一个Mesh,里面还提到了一个SubMesh的概念。Mesh是对于三维物体对象的封装概念,一个很容易的需求是,有的地方我希望用到材质A,有的地方我希望用到材质B,我不想把这个Mesh进行拆分,那么很简单,就在这个Mesh中划分两个子Mesh就可以了。
2. 详论
2.1. 实现
我们创建如下脚本,并且随便挂接两个不同的材质在属性material1和属性material2上:
using UnityEngine;
using UnityEngine.Rendering;
[ExecuteInEditMode]
public class Note5Main : MonoBehaviour
{
public Material material1;
public Material material2;
// Start is called before the first frame update
void Start()
{
Mesh mesh = CreateMesh();
MeshFilter mf = gameObject.GetComponent<MeshFilter>();
if (mf == null)
{
mf = gameObject.AddComponent<MeshFilter>();
}
mf.sharedMesh = mesh;
MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer>();
if (meshRenderer == null)
{
meshRenderer = gameObject.AddComponent<MeshRenderer>();
}
Material[] materials = new Material[2];
materials[0] = material1;
materials[1] = material2;
meshRenderer.materials = materials;
}
Mesh CreateMesh()
{
Mesh mesh = new Mesh();
const int vertexCount = 8;
Vector3[] vertices = new Vector3[vertexCount]
{
new Vector3(-5, 0, 0),
new Vector3(-5, 5, 0),
new Vector3(5, 0, 0),
new Vector3(5, 5, 0),
new Vector3(-5, -5, 0),
new Vector3(-5, 0, 0),
new Vector3(5, -5, 0),
new Vector3(5, 0, 0),
};
Vector3[] normals = new Vector3[vertexCount]
{
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
new Vector3(0, 0, -1),
};
Vector2[] uv = new Vector2[vertexCount]
{
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 0),
new Vector2(1, 1),
new Vector2(0, 0),
new Vector2(0, 1),
new Vector2(1, 0),
new Vector2(1, 1),
};
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uv;
int[] triangles = new int[12] {
0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6 };
MeshUpdateFlags flags = MeshUpdateFlags.DontValidateIndices | MeshUpdateFlags.DontResetBoneBounds
| MeshUpdateFlags.DontNotifyMeshUsers | MeshUpdateFlags.DontRecalculateBounds;
//MeshUpdateFlags flags = MeshUpdateFlags.Default;
int indexCount = triangles.Length;
mesh.SetIndexBufferParams(indexCount, IndexFormat.UInt32);
mesh.SetIndexBufferData(triangles, 0, 0, indexCount, flags);
mesh.subMeshCount = 2;
SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, 6);
mesh.SetSubMesh(0, subMeshDescriptor1, flags);
SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(6, 6);
mesh.SetSubMesh(1, subMeshDescriptor2, flags);
return mesh;
}
// Update is called once per frame
void Update()
{
}
}
我这里得到的效果如下:

2.2. 解析
很明显,我这里创建了两个四边形,并且将其放到一个Mesh下。创建顶点属性我使用的是简单接口,创建顶点索引属性信息使用的是高级接口。关键点在于对SubMesh的描述:
mesh.subMeshCount = 2;
SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, 6);
mesh.SetSubMesh(0, subMeshDescriptor1, flags);
SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(6, 6);
mesh.SetSubMesh(1, subMeshDescriptor2, flags);
SubMeshDescriptor类定义了从那个顶点索引开始,之后多长的空间是一个SubMesh,也就是对Mesh做了一个划分。另外,GameObject上挂接的材质个数也要对应:
MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer>();
if (meshRenderer == null)
{
meshRenderer = gameObject.AddComponent<MeshRenderer>();
}
Material[] materials = new Material[2];
materials[0] = material1;
materials[1] = material2;
meshRenderer.materials = materials;
MeshRenderer上能挂接多个材质,有多少个SubMesh就应该有多少个材质,它们是一一对应的。数量没对应上Unity编辑器会报错。
通过划分SubMesh的方式来描述一个Mesh通常是用于存在多个材质的情况,如果使用的都是同一个材质,就最好不要作SubMesh划分。我们打开Frame Debug,可以看到:
一个Mesh分成了居然两个渲染指令来实现!原因在于图像引擎通常是一个状态机,一个材质需要对应一个渲染指令,这就是为什么我们往往要尽可能复用材质,减少不同材质的个数。
3. 参考
边栏推荐
- What is fake sharing after filling the previous hole?
- 微信论坛交流小程序系统毕业设计毕设(8)毕业设计论文模板
- Some parameters of Haikang IPC
- Comparison of various development methods of applets - cross end? Low code? Native? Or cloud development?
- Kubernetes' simplified data storage storageclass (creation, deletion and initial use)
- Mitsubishi PLC SLmP (MC) protocol
- 网络安全-对操作系统进行信息查询
- 网络安全-钓鱼
- 肠道里的微生物和皮肤上的一样吗?
- What is ADC sampling rate (Hz) and how to calculate it
猜你喜欢

微信论坛交流小程序系统毕业设计毕设(5)任务书

微信论坛交流小程序系统毕业设计毕设(3)后台功能

Understand the session, cookie and token at one time, and the interview questions are all finalized

Database daily question --- day 22: last login

成年人只有一份主业是要付出代价的,被人事劝退后,我哭了一整晚

Microbial health network, how to restore microbial communities
![[record of question brushing] 3 Longest substring without duplicate characters](/img/44/1cd8128d93c9c273e0f4718d84936e.png)
[record of question brushing] 3 Longest substring without duplicate characters

30讲 线性代数 第五讲 特征值与特征向量

微信论坛交流小程序系统毕业设计毕设(6)开题答辩PPT

iNFTnews | NFT技术的广泛应用及其存在的问题
随机推荐
Some parameters of Haikang IPC
GEE(三):计算两个波段间的相关系数与相应的p值
QT graphicsview graphical view usage summary with flow chart development case prototype
Adrnoid开发系列(二十五):使用AlertDialog创建各种类型的对话框
成年人只有一份主业是要付出代价的,被人事劝退后,我哭了一整晚
Anta DTC | Anta transformation, building a growth flywheel that is not only FILA
Knowledge drop - PCB manufacturing process flow
ArcGIS:字段赋值_属性表字段计算器(Field Calculator)依据条件为字段赋值
知识点滴 - PCB制造工艺流程
PMP项目管理考试过关口诀-1
定位到最底部[通俗易懂]
【刷题记录】3. 无重复字符的最长子串
iNFTnews | NFT技术的广泛应用及其存在的问题
网络安全-sqlmap与DVWA爆破
微信论坛交流小程序系统毕业设计毕设(6)开题答辩PPT
微信论坛交流小程序系统毕业设计毕设(8)毕业设计论文模板
What is fake sharing after filling the previous hole?
JS triangle
USB(十四)2022-04-12
Microbial Health Network, How to restore Microbial Communities