Unity3D学习笔记4——创建Mesh高级接口

简介: Unity3D学习笔记4——创建Mesh高级接口

Unity3D学习笔记4——创建Mesh高级接口

目录

1. 概述

在文章Unity3D学习笔记2——绘制一个带纹理的面中使用代码的方式创建了一个Mesh,不过这套接口在Unity中被称为简单接口。与其相对应的,Unity还提供了一套高级API来创建Mesh。

2. 详论

根据Unity文档的论述,使用高级接口能够得到更高的性能,能够跳过一些验证检查。但是这并不是最关键的,简单接口有个最大的缺点是顶点个数超过65535个时就有问题(至少在2019.4.3f1版本还是这样)。

话不多说,直接上代码:

using UnityEngine;
using UnityEngine.Rendering;
[ExecuteInEditMode]
public class Note4Main : MonoBehaviour
{
    public Material material;
    // Start is called before the first frame update
    void Start()
    {
        Mesh mesh = new Mesh();
        mesh.name = "quad";
        //顶点数据
        VertexAttributeDescriptor[] vertexAttributeDescriptorList = new[]{
             new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
             new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3),
             new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2)};
        const int vertexCount = 4;
        const int verticesAttributeBufferLength = vertexCount * (3 + 3 + 2);
        float[] verticesAttributeBuffer = new float[verticesAttributeBufferLength] {
            -5, -5, 0, 0, 0, -1,0, 0,
            -5, 5, 0, 0, 0, -1, 0, 1,
            5, -5, 0, 0, 0, -1, 1, 0,
            5, 5, 0, 0, 0, -1, 1, 1
        };
        mesh.SetVertexBufferParams(vertexCount, vertexAttributeDescriptorList);
        mesh.SetVertexBufferData(verticesAttributeBuffer, 0, 0, verticesAttributeBufferLength, 0);
        int[] triangles = new int[6] { 0, 1, 2, 1, 3, 2 };
        int indexCount = triangles.Length;
        //顶点索引文件
        mesh.SetIndexBufferParams(indexCount, IndexFormat.UInt32);
        mesh.SetIndexBufferData(triangles, 0, 0, indexCount);
        //子Mesh描述
        mesh.subMeshCount = 1;
        SubMeshDescriptor subMeshDescriptor = new SubMeshDescriptor(0, indexCount);
        mesh.SetSubMesh(0, subMeshDescriptor);
        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>();
        }
        meshRenderer.material = material;
    }
    // Update is called once per frame
    void Update()
    {
    }
}

最后可以直接得到与Unity3D学习笔记2——绘制一个带纹理的面一样的效果。如果有一些图形基础,就会很容易理解这段代码。都是申请一个buffer,定义顶点的描述信息,这里是按照x,y,z,nx,ny,nz,u,v的顺序,一个顶点一个顶点进行排列。接着是定义一个顶点索引buffer;不同的是增加了一个对于子mesh的描述。在Unity里,一个Mesh可以包含多个子Mesh,每个子Mesh都能对应MeshRenderer中的多个材质中的一个。

3. 其他

  1. 根据官方文档论述,这套高API性能更高。但个人使用感觉不是很明显。跳过验证的设置也可能带来一些其他问题,我一般用默认设置。
  2. 另一个优点是,可以避免简单接口中顶点个数超过65535时Mesh绘制不正确的问题。理论上,绘制的批次越少越好,这就要求尽可能合批次绘制,同样顶点个数的物体分多个mesh绘制,性能比不上使用一个大的Mesh一次绘制。
  3. 官方文档还提到了有其他接口可以通过C# Jobs和Burst创建Mesh,C# Jobs与多线程相关,难道意味着可以在多线程下创建Mesh了?有待进一步研究。

4. 参考

  1. Unity3D学习笔记2——绘制一个带纹理的面
  2. Unity Documentation - Mesh

分类: Unity3D

标签: Mesh , Unity3D


相关文章
|
编解码 图形学
浅谈Unity之ShaderGraph学习笔记-03
每日记录自己学习unity的心得和体会
|
3月前
|
缓存 图形学
Unity3D学习笔记12——渲染纹理
Unity3D学习笔记12——渲染纹理
39 2
|
3月前
|
API C# 图形学
Unity3D学习笔记9——加载纹理
Unity3D学习笔记9——加载纹理
39 2
|
3月前
|
API 图形学 异构计算
Unity3D学习笔记7——GPU实例化(2)
Unity3D学习笔记7——GPU实例化(2)
25 2
|
3月前
|
存储 缓存 图形学
Unity3D学习笔记11——后处理
Unity3D学习笔记11——后处理
57 1
|
3月前
|
测试技术 C# 图形学
Unity3D学习笔记10——纹理数组
Unity3D学习笔记10——纹理数组
50 0
|
3月前
|
图形学 异构计算
Unity3D学习笔记8——GPU实例化(3)
Unity3D学习笔记8——GPU实例化(3)
45 0
|
3月前
|
存储 API 图形学
Unity3D学习笔记6——GPU实例化(1)
Unity3D学习笔记6——GPU实例化(1)
58 0
|
3月前
|
API 图形学 索引
Unity3D学习笔记5——创建子Mesh
Unity3D学习笔记5——创建子Mesh
29 0
|
3月前
|
C# 图形学 C语言
Unity3D学习笔记3——Unity Shader的初步使用
Unity3D学习笔记3——Unity Shader的初步使用
47 0