(一)mesh基础

概述

本篇为Unity Mesh基础的第一篇,通过一个最基本的平面四边形网格来进行阐述。在此之前先对网格(mesh)做一个简介。网格为最基本的模型表达,通过点构成线,再由线构成三角形,最后由三角形构成面,然后通过材质来进行网格表面的表达,如阴影,贴图等。Unity除了ui的mesh,其他都需要MeshFilter来确定网格形状,通过Material以及MeshRenderer来进行网格渲染。

Mesh的组成

Mesh由顶点组成,再有三个顶点构成。所以Mesh必须定义顶点以及顶点如何构成三角形,这是最基本的三个要素,其次还需要定义uv来确定贴图如何覆盖在图形表面,如果需要还需定义顶点的法线或者切向,法线跟光照有关,而切向则会影响纹理凹凸问题,本文以四边形为例进行阐述。

四边形顶点

顶点个数为4,即左下,右下,右上以及左上。size为正方向尺寸。

    protected override Vector3[] Vertices
    {
        get
        {
            Vector3[] vertices = new Vector3[4];
            vertices[0] = Vector3.zero * size;
            vertices[1] = Vector3.right * size;
            vertices[2] = new Vector3(1, 1, 0) * size;
            vertices[3] = Vector3.up * size;

            return vertices;
        }
    }

三角形排列

三角形排列为int类型数组,保存顶点的索引号,每三个组成一个三角形。下述代码即为左下,左上,右下组成第一个三角形,剩下组成第二个三角形,排列顺序为顺时针方向。

    protected override int[] Triangles
    {
        get
        {
            int[] triangles = new int[6]
            {
                0,3,1,1,3,2
            };

            return triangles;
        }
    }

Mesh的uv

如果给网格赋值贴图,则需要定义uv,如下定义则为图片左下角对应mesh的左下角,右上角对应右上角。

    protected override Vector2[] Uvs
    {
        get
        {
            Vector2[] uvs = new Vector2[4];
            uvs[0] = new Vector2(0, 0);
            uvs[1] = new Vector2(1, 0);
            uvs[2] = new Vector2(1, 1);
            uvs[3] = new Vector2(0, 1);

            return uvs;
        }
    }

完整代码

基类

基类主要是通过OnDrawGizmos来绘制顶点,利于更直观观察。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class CreateMeshBase : MonoBehaviour
{
    MeshFilter meshFilter;

    protected Mesh mesh;

    protected virtual Vector3[] Vertices { get; }
    protected virtual int[] Triangles { get; }
    protected virtual Vector3[] Normals { get; }
    protected virtual Vector2[] Uvs { get; }
    protected virtual string MeshName { get; }

    protected virtual void Start()
    {
        GetMeshFilter();
    }

    protected virtual void Reset()
    {
        GetMeshFilter();
    }

    protected virtual void OnValidate()
    {
        GetMeshFilter();
    }

    void GetMeshFilter()
    {
        if (meshFilter == null)
        {
            meshFilter = GetComponent<MeshFilter>();
            mesh = new Mesh();            
        }

        mesh.triangles = null;
        mesh.uv = null;
        mesh.vertices = null;

        mesh.name = MeshName;
        mesh.vertices = Vertices;
        mesh.triangles = Triangles;
        mesh.uv = Uvs;

        meshFilter.mesh = mesh;
    }

    private void OnDrawGizmos()
    {
        if (Vertices == null) return;

        Gizmos.color = Color.red;
        Gizmos.DrawSphere(Vector3.zero, 0.5f);

        Gizmos.color = Color.blue;

        for (int i = 0; i < Vertices.Length; i++)
        {
            Gizmos.DrawSphere(Vertices[i], 0.3f);
        }
    }
}

Quad参数

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateQuad : CreateMeshBase
{
    public int size = 5;

    protected override Vector3[] Vertices
    {
        get
        {
            Vector3[] vertices = new Vector3[4];
            vertices[0] = Vector3.zero * size;
            vertices[1] = Vector3.right * size;
            vertices[2] = new Vector3(1, 1, 0) * size;
            vertices[3] = Vector3.up * size;

            return vertices;
        }
    }

    protected override int[] Triangles
    {
        get
        {
            int[] triangles = new int[6]
            {
                0,3,1,1,3,2
            };

            return triangles;
        }
    }

    protected override string MeshName
    {
        get
        {
            return "Simple quad";
        }
    }

    protected override Vector2[] Uvs
    {
        get
        {
            Vector2[] uvs = new Vector2[4];
            uvs[0] = new Vector2(0, 0);
            uvs[1] = new Vector2(1, 0);
            uvs[2] = new Vector2(1, 1);
            uvs[3] = new Vector2(0, 1);

            return uvs;
        }
    }
}

使用

使用时新建一个空游戏物体,挂载上述脚本,然后新建材质,并将材质赋值给MeshRenderer即可。

上一篇:ovm 格式的 六面体网格 样例 正方体的生成程序和文件


下一篇:Three.js Example 注解 —— webgl_morphtargets.html