当前位置:网站首页>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. 参考
边栏推荐
- [network] Introduction to C language
- Database daily question --- day 22: last login
- Classification and prediction of heartbeat signal
- 网格(Grid)
- 微生物健康網,如何恢複微生物群落
- 微信论坛交流小程序系统毕业设计毕设(4)开题报告
- 为什么市场需要低代码?
- Years of summary, some core suggestions for learning programming
- Network security - phishing
- OC variable parameter transfer
猜你喜欢
Wechat forum exchange applet system graduation design completion (1) development outline
Anta DTC | Anta transformation, building a growth flywheel that is not only FILA
Database daily question --- day 22: last login
There is another problem just online... Warm
微生物健康網,如何恢複微生物群落
What is fake sharing after filling the previous hole?
Microbial health network, how to restore microbial communities
高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
30讲 线性代数 第五讲 特征值与特征向量
PMP project management exam pass Formula-1
随机推荐
Cascade-LSTM: A Tree-Structured Neural Classifier for Detecting Misinformation Cascades-KDD2020
网络安全-联合查询注入
今日创见|企业促进创新的5大关键要素
位运算(Bit Operation)
Use JfreeChart to generate curves, histograms, pie charts, and distribution charts and display them to JSP-1
十四、数据库的导出和导入的两种方法
Grid
Bit operation
【微服务|SCG】gateway整合sentinel
Use JfreeChart to generate curves, histograms, pie charts, and distribution charts and display them to jsp-2
ArcGIS: two methods of attribute fusion of the same field of vector elements
PMP project management exam pass Formula-1
Two kinds of curves in embedded audio development
微信论坛交流小程序系统毕业设计毕设(7)中期检查报告
DTC社群运营怎么做?
Network security - install CentOS
Exploratory data analysis of heartbeat signal
安踏DTC | 安踏转型,构建不只有FILA的增长飞轮
One question per day - pat grade B 1002 questions
网络安全-钓鱼